简体   繁体   中英

Are Unowned references set to 'nil' when deinitialized?

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'

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 the unowned 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 is nil , and if you do your program will crash.

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:

Note also that Swift guarantees your app will crash if you try to access an unowned reference after the instance it references is deallocated. You will never encounter unexpected behavior in this situation. Your app will always crash reliably, although you should, of course, prevent it from doing so.

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 to nil 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 technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM