What is the difference between String? and String! (two ways of creating an optional variable)?

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.

Leave a Comment