简体   繁体   中英

Why are there weak _and_ unowned? Why can we just not always use weak?

I just read the ARC section in the Swift book and a few other related posts concerning weak and unowned references.

After my readings, I do have a clear understanding on what they are and in what situations each of them are to be used (see also this SO post which gives a great explanation of this).

However, I fail to understand why Apple even came up with these two solutions? Essentially, from a MM perspective, both come down to not creating a strong reference to the referred object (ie not increasing its retainCount ). So, why even bother and provide two MM primitives here?

Now, developers need to understand when to use which of the two, and Apple did a great job in explaining the different scenarios, but they didn't say why . Wouldn't it have been simpler to eg only provide weak so that developers don't need to dig into the docs and understand the different use cases?

I guess, another way to phrase the question is, why at all should we use unowned , except for Apple telling us so? At least from a MM standpoint, this wouldn't make a difference and using weak where according to the docs we should use unowned wouldn't create a memory leak?!

The difference is in the optionality of variables. Like Apple says in the Unowned References section of the link you provided:

Unlike a weak reference, however, an unowned reference is assumed to always have a value. Because of this, an unowned reference is always defined as a nonoptional type.

The usage of this is more visible in a closure block. Here you do not have to use ? operator or get a reference on the object if you use it inside the closure.

Instead of writing this:

UIView.animateWithDuration(0.2) {
    [weak self]
    () -> Void in
    self?.view.layoutIfNeeded()
}

However, if you can be sure that the reference to self will not be released before the animation and you can simply write unowned and do not have to use the ? operator or unwrap it with an if let statement:

UIView.animateWithDuration(0.2) {
    [unowned self]
    () -> Void in
    self.view.layoutIfNeeded()
}

@Kádi's answer about weak variables being optional is correct, but incomplete.

Weak and unowned have a difference in meaning outside of Swift's Optional semantics. A weak reference is more accurately named an auto-zeroing weak reference. The system knows about an object stored in a weak variable, and when the object is deallocated, goes to the extra work to zero out the value. As a consequence of that, weak variables are optionals in Swift.

Unowned pointers are not memory managed at all. They are a raw memory pointer that can take any value. (They can still be typed to point to a particular type of structure, so they aren't always "raw" in the way a C void pointer is raw.) Unowned pointers are useful for pointing to malloc'ed memory, pointer arithmetic, and the like. Declaring a pointer type as unowned basically tells the compiler "Don't worry about it. I know what I'm doing." The burden is then on you to make sure the pointer is always valid, before you try to dereference it, and also manage the memory behind the pointer yourself.

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