简体   繁体   中英

What is the difference between self and unowned self in Swift?

I was wondering what is the difference between the following two expressions?

foregroundNotification = NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationWillEnterForegroundNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { 
  (notification:NSNotification!) -> Void in
   // do something
})

and (with unowned self ):

foregroundNotification = NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationWillEnterForegroundNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { 
  [unowned self] (notification:NSNotification!) -> Void in
   // do something
})

Swift memory management is performed via reference counting. You can read a good summary of reference counting and its implications in the official Swift docs .

However, to summarize – the problem with reference-counted memory management is the risk of reference cycles – object A holds a reference to object B, and object B holds a reference to object A. Even when no-one is using either object A or B any more, they keep each other alive, preventing memory from being freed, their deinit methods being called etc.

There are two solutions to reference cycles in Swift – weak references, and unowned references.

Weak references don't count towards the an object's reference count. So if object B has only a weak reference to object A, then when all other strong references are removed, object A is destroyed. Obviously the risk is that object B might then try to use object A. This is why in Swift weak references are optionals – you have to unwrap them (which returns a strong rather than weak reference) to check that the referred-to object is still there.

Unowned references are similar in that they don't cause objects to be retained. However, unlike weak references they are not optionals and do not need to be checked first. Instead, from the docs:

If you try to access an unowned reference after the instance that it references is deallocated, you will trigger a runtime error. Use unowned references only when you are sure that the reference will always refer to an instance.

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.

This means you should only use them in circumstances where you know, based on your program's logic, that there is no way the unowned object will ever be destroyed before the object holding the unowned reference. The example in the Swift docs is a Customer and a CreditCard – a credit card is known never to exist without a customer, therefore it can have an unowned reference to its customer without the risk of that customer being destroyed while the credit card is still in use.

In addition to being easier to use (no need to unwrap), unowned references have lower overall overhead, so there's a bit of a risk/reward payoff. Even though weak references don't contribute to an object's reference count, they do still need some level of tracking, unowned references less-so.

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