简体   繁体   中英

Why specify [unowned self] in blocks where you depend on self being there?

I want self to be non-nil and I'm sure it will be, during the blocks execution. So why explicitly specify [unowned self] ?

object.executeBlock {
    date = self.lastModified
}

vs

object.executeBlock { [unowned self] in
    date = self.lastModified
}

Edit: Well i'm getting down votes so let's try again. Q: Let's say I have a problem. That problem is that I would like to prevent a reference cycle. I have two options. I could use [unowned self] or I could use [weak self]. My question therefore, is this: from these two options, why would I choose [unowned self] ? Why not choose [weak self] everytime ?

"The Language Guide claims you should use unowned if the closure and containing object reference each other and will be destroyed at the same time. Presumably that's to avoid the cost of safely nil'ing out a weak reference in an object that's about to dealloc anyway."

http://www.russbishop.net/swift-capture-lists

So [unowned self] makes self an an implicitly unwrapped optional, for the convenience of not unwrapping it yourself, at the risk of a crash if of course it is actually nil.

The only time where you really want to use [unowned self] or [weak self] is when you would create a strong reference cycle. A strong reference cycle is when there is a loop of ownership where objects end up owning each other (maybe through a third party) and therefore they will never be deallocated because they are both ensuring that each other stick around.

Do you have a strong reference cycle there?

I answered this elsewhere. Here's the Cliff notes:

If self could be nil in the closure use [weak self].

If self will never be nil in the closure use [unowned self].

If it's crashing when you use [unowned self] I would guess that self is nil at some point in that closure, which is why you had to go with [weak self] instead.

I really liked the whole section from the manual on using strong, weak, and unowned in closures:

https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html

Why [unowned self]? self points to object, object has executeBlock, and executeBlock points back to self, creating a memory cycle.

However when you say [unowned self]: the system will not keep self in memory in order to to make the closure work. it will assume that self is always there when the closure is executed. If not for some reason, there won't be undefined behavior or anything like that but your app will crash as it is a runtime error.

This is how it was explained by Paul Hegarty, stanford iOS dev teacher.

In a situation where self could conceivably be nil at the time it's used in the closure, you're compelled to use weak semantics (or risk a crash).

In a case where you can reason that self will never be nil , you can choose to specify either: "choose" in the sense that both are correct and will work. Arguably one could be considered "more correct" than the other, in the sense that both semantics satisfy the requirements but one is more specific.

Two reasons you might want to specified unowned instead of self :

  • Convenience
  • Documentation

An unowned reference will be more convenient to use because it doesn't need to be unwrapped. It may also be more efficient, since the compiler may not have to produce as much cleanup code for safe deallocation.

In terms of documentation, you're making a kind of assertion about something your program believes to be true. If that assumption (assuming it was valid) is violated, you may like to find out about it in the form of a crash.

Subsequently, this may also make usage of the variable less exhausting: you think about it and document your reasoning that it must always exist up front, and then each time you use it, you don't have to expend further mental energy wondering "what do I do if this isn't here?".

Arguably, using a let binding or guard statement also achieves the latter.

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