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...
Difference between weak reference and unowned reference The weak reference is an optional type, which means weak reference will set to nil once the instance it refers to frees from memory. On the other hand, unowned reference is a non-optional type, it never will be set to nil and always have some value.
The key difference between a strong and a weak or unowned reference is that a strong reference prevents the class instance it points to from being deallocated. That is very important to understand and remember. ARC keeps track of the number of strong references to a class instance.
According to Apple's docs: “Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime. Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialisation.”
No, weak and optional are not the same, but there is some interplay between the two. Optional just means that a variable can be nil , either by assigning nil yourself, or becoming nil through some other means. The weak keyword has to do with memory management.
Unowned References in Swift Another solution to retain cycles is an unowned reference. Like a weak reference, an unowned reference does not increment or decrement the reference count of an object. However, unlike a weak reference, the program guarantees to the Swift compiler that an unowned reference will not be nil when it is accessed.
Weak References are one solution to retain cycles in Swift. A weak reference does not increment or decrement the reference count of an object. Since weak references do not increment the reference count of an object, a weak reference can be nil. This is because the object could be deallocated while the weak reference is pointing to it.
Our focus will be on when to use weak and when it is better to use unowned by real-world examples. Define a capture in a closure as an unowned reference when the closure and the instance it captures will always refer to each other, and will always be deallocated at the same time.
Contrary to strong reference, weak reference has no impact on an object’s reference count. Meaning that if we declare a weak variable pointing to an object, that object’s reference count will remain the same as it was before. Lets see what that means in practice with the following simple example:
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:
nil
if that object goes out of existence. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With