Before get into the answers, you may want to checkout the quizzes from HERE
Tested with Swift 2.1 & Xcode 7.2
init() get called,
property3 is already initialized. Then
init() get called and initialize property1 & property2 inside. Finally, we access the property explicitly to initialize property4.
// => 3, 1, 2, 4,
- Assign a new value inside
init()will not fire
didSet. So property value changed from
4, then printed
- Assign a new value inside
didSet. So actually the value path is:
1 -> 4 -> 2 -> 5 -> 3, then printed
- Should notice that we can actually access
selfinside property observing, it will not cause infinite loop.
// Without calling `config()` => 4 // With calling `config()` => 3
case 1, assign the property will not fire getter, so technically we can do this even in his own getter.
case 2, on the other hand, we fire getter in his own getter. So yes, infinite loop.
Case 3is as same as
case 2, try to assign the property in setter will cause infinite loop.
Case 4is as same as
case 1, call getter in his own setter is OK.
Case 5is a combination of
case 4, we try to call getter from setter and vice versa. It will cause an infinite loop between getter & setter.
- Should notice that usually we don’t have this kind need. We’ll get a warning if we try to access the property in his own getter or setter without explicitly using
// case 1 => 1 // case 2 => runtime crash (infinit loop) // case 3 => runtime crash (infinit loop) // case 4 => 1 // case 5 => runtime crash (infinit loop)
- We can not access
selfin non-lazy stored property. Quite obviously.
- We can access
selfwhen stored property is
lazy. So it’s safe to access other property.
- When try to access property getter in his own initializer, it will cause an infinite loop. Also quite obviously.
- Only assign the value will not called getter, so it is safe from infinite loop. Even this approach is kind of meaningless ¯\_(ツ)_/¯
// case 1 => compiler error // case 2 => 1, 2 // case 3 => runtime crash (infinit loop) // case 4 => 2
- Case 1: Override and re-assign the property value in his own
didSetwill cause infinite loop.
- Case 2: We can safely access
superin property observing. In this case the value actually from super’s getter, so it printed
- Should notice that assignment of an overridden property in subclass’s
init()will actually fire
// case 1 => runtime crash (infinit loop) // case 2 => 1
- The property is override by a computed property with an empty setter, which means
didSetwon’t get fired since it can not be assigned with a new value. So it will always return value from getter:
case 2, we assign a new value in the setter, it will fire
didSet, so the final value will be
// case 1 => 1 // case 2 => 3
Well, I hope you guys had a good time from this quizzes. Compare with Objective-C’s property/iVar, Swift brings us a way more powerful property system, a lot more possibilities. There are some circumstances you may never have in production, otherwise it probably a signal that you should refactor your codes. But hey, there is still a lot of fun to discover more details of the edge cases, right?
One more thing, Swift is still moving forward fast. Or even faster after been open source. So things may change, for instance, if the proposal about “Property behaviors” of Joe Groff is adapted, some of those quiz/answer may be obsoleted very soon. So, keep moving, keep learning 😉
Feel free to ping me on twitter by @wangshengjia if I am wrong about something I’ve mentioned or you have any question/anything. Enjoy 🎉🍻
Victor S. Wangwww.allblue.me
startup, freelancer, developer, technology enthusiasts, innovation, passion