The real benefit to using implicitly unwrapped optionals (declared with the !) is related to class initialisation when two classes point to each other and you need to avoid a strong-reference cycle. For example:
Class A <-> Class B
Class A's init routine needs to create (and own) class B, and B needs a weak reference back to A:
class A {
let instanceOfB: B!
init() {
self.instanceOfB = B(instanceOfA: self)
}
}
class B {
unowned let instanceOfA: A
init(instanceOfA: A) {
self.instanceOfA = instanceOfA
}
}
Now,
- Class B needs a reference to class A to be initialised.
- Class A can only pass
self
to class B's initialiser once it's fully initialised.
- For Class A to be considered as initialised before Class B is created, the property
instanceOfB
must therefore be optional.
However, once A's been created it would be annoying to have to access instanceOfB using instanceOfB! since we know that there has to be a B
To avoid this, instanceOfB is declared as an implicity unwrapped optional (instanceOfB!), and we can access it using just instanceOfB. (Furthermore, I suspect that the compiler can optimise the access differently too).
An example of this is given on pages 464 to 466 of the book.
Summary:
- Use ? if the value can become nil in the future, so that you test for this.
- Use ! if it really shouldn't become nil in the future, but it needs to be nil initially.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…