I'm confused on this topic in swift where it is said that unowned references must always have a value and cannot be optional, also meaning they cannot be set to 'nil'....well I just saw a program on the Apple documents for swift that instance 'A' with an unowned reference to instance 'B' was deinitialized and deallocated right after instance 'B' was deinitialized/deallocated......when a var is deinitialzed/dealloc doesn't it mean they are set to 'nil'??? Instance B is an optional so sure it can hold 'nil' but why did instance 'A' get deinitialized when its supposed to always have a value????
PS: If this helps..... instance 'B' was an optional type with a strong reference to instance 'A'
It is meaningless to talk about what an
unowned
variable "holds" after the object it points to has been deallocated, because Swift guarantees that your app will crash if you ever try to access the variable after the object it points to has been deallocated:An object is deinitialized when its strong reference count drops to 0, but it is not deallocated until its weak reference count also drops to zero.
"Deinitializing" an object means that its
deinit
function is executed if it has one, releasing any resource that it holds, and clearing any references that it may have (potentially deinitializing and deallocating more objects). "Deallocating" is when the memory is reclaimed by the runtime. A deinitialized object's reference counting header is still valid.When you access a
weak
reference, the Swift runtime ensures that the object is still in an initialized state. If it isn't, the weak reference is set tonil
and the deinitialized object's weak reference count is decremented.Unowned references also count towards the weak reference count. When you access an unowned reference, the Swift runtime also ensures that the object is in an initialized state; but if it is not, instead of clearing the reference (it can't do that because it is not optional), it crashes your program.
This effectively makes an unowned reference behave like an implicitly-unwrapped optional, whereas a weak reference behaves like an optional.
The tradeoff for self-zeroing weak references and clean-crashing unowned references is that an object's backing memory cannot be reclaimed until all of its weak references have been tested or deinitialized, and until all of its unowned references have been deinitialized.
Source: Swift runtime code
The point of an
unowned
reference is to hold a weak reference to something that you are guaranteeing (based on your application logic) will not be deallocated prior to the object that has theunowned
reference. You can read more in the documentation.In a sense it is a similar thing to an implicitly unwrapped optional type (such as
String!
). You're telling the compiler that you won't ever access the value when it isnil
, and if you do your program will crash.