简体   繁体   中英

Is unowned logically equivalent to weak! in Swift

Will these blocks always fail under the same circumstances (when the closure is being executed but self was deallocated)?

{ [unowned self] in
    //use self
    self.number = self.number + 1
}

{ [weak self] in
    //use self!
    self!.number = self!.number + 1
}

Unowned reference does not keep strong reference to the self, but it makes an assumption that the object always has some value (is not nil) and if, some how self deallocates while executing the block, the above code crashes.

For the case of weak, as in your example, weak is an optional type inside the block, so there could also be a value or it could be nil. It is your responsibility to check if the value exists and call methods on it. As above if you use unwrapping operator (!), when self has been deallocated, then it surely crashes. So, both the version of the code crashes, if it happens such that the block is still executing and self is deallocated in the mean time.

So, I suggest to use weak to safeguard such crashes using the optional checks,

{ [weak self] in
    if let me = self {
       me.number = me.number + 1
    }
}

Yes, those are equivalent. That is the point of unowned -- it's just like weak , except that you don't have to deal with an optional and unwrap it, because its type is the unwrapped non-optional type; it is weak that is always forcibly unwrapped at every appearance.

Should use it like this

{ [weak self] in

    guard let weakSelf = self else {
       return 
    }

    weakSelf.number = weakSelf.number + 1
}

Thanks to @José 's comment, be aware that even though the following code works at the moment, but it is considered a compiler bug and should be avoided https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160118/007425.html .

You can also unwrap self like this:

{ [weak self] in

    guard let `self` = self else {
       return 
    }

    // Now you can use `self` safely
    self.number = self.number + 1
}

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