9
votes

This is allowed in Swift 5.0:

class Person { 
    unowned var child: Person?
}

This is supported by this release notes:

unowned and unowned(unsafe) variables now support Optional types. (47326769)

I understood exactly the difference between weak and unowned in Swift 4.2 and before. However, I am not sure why Apple decided to make the unowned an optional type. Even in the docs (which are docs for Swift 5.0) this implemented 'proposal' (where can I even find that proposal with the motivation to add optional unowned references?) isn't updated, because it says:

An unowned reference is expected to always have a value. As a result, ARC never sets an unowned reference’s value to nil, which means that unowned references are defined using non-optional types.

Above isn't true anymore. The only functional difference that Apple states is that an unowned reference is expected to have an equal or longer lifetime than the object holding that reference. Well, I am curious about the technical use of this.

What difference does it make when I use a weak reference vs an optional unowned reference? Or is the only difference that optional unowned should be used when the referencing object has a longer lifetime? I would expect there must be more...

1

1 Answers

13
votes

You've misunderstood the release note and the meaning of the change in the language.

why Apple decided to make the unowned an optional type

They didn't. You can, and usually will, still say

unowned let owner : MyViewController

The only change here is that the unowned variable can be an Optional, which was illegal previously. This change takes care of an annoying edge case, that's all.

Above isn't true anymore

Yes, it is. Things are completely unchanged from before:

  • Weak references must be typed as Optional; they do not retain the object referred to, but they track the object referred to, and revert to nil if that object goes out of existence.
  • Unowned references do not retain the object referred to and do not track the object referred to, so it's up to you to prevent that object from going out of existence or you may end up with a dangling pointer and a crash.

The only thing that's changed is that there used to be an additional rule that an unowned reference type could not be an Optional. That rule is now gone.

As you rightly point out, if the unowned reference type is an Optional, this must be a var reference, not a let reference (because having this be an Optional would make no sense if you didn't have the power to change it from nil to an actual value and vice versa).

A typical use case is very much like what you yourself provided:

class Node {
    unowned var parent: Node?
}

It seems reasonable to say that this Node may or may not have a parent (because it might be at the top of the graph), but that if it does have a parent, that parent should be unowned (a parent should retain its child, but a child should not retain its parent). Previously, the only way to say that was to make this a weak reference, which entails some unnecessary overhead, and is otiose, because we can absolutely guarantee that if a node has a parent, the parent will outlive the child. Now, you can say what you mean, which is generally a good thing.