Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Swift, unowned vs. weak reference [duplicate]

If you have a Dog with a weak reference to Bone, that means that the Dog is the 'owner' of the reference in this situation, and it USES bone, but bone can go out of existence and Dog can still function (because the reference to bone is an optional).

However with 'unowned', it seems to be that the keyword 'unowned' is used not in the owner's declaration of the reference, but in the other object. For instance, Bone's reference to its dog is marked as 'unowned'.

Unowned is not safe. It can crash if the owner goes out of existence at some point in the program, and it cannot be an optional. Why would one ever use unowned as opposed to a weak reference?

Why not just use weak? from my understanding it just has to do with failing loudly vs. failing silently. In the case of an unowned, the app will always crash if bone ends up without a dog, whereas if we use weak, you will end up with a bone that still exists, with a 'ghost' dog.

like image 287
user7024499 Avatar asked Nov 30 '22 09:11

user7024499


1 Answers

Strong & Weak references

A weak reference is a reference that does not keep a strong hold on the instance it refers to, and so does not stop ARC from disposing of the referenced instance.

So when A has a weak reference to B, then A is NOT the owner.

Example (where A is Bone and B is Dog)

class Dog {
    var bone: Bone?
}

class Bone {
    weak var belongsTo: Dog?
}

Strong Reference

Here a Dog can have a Bone. In that case it's the owner of that Bone. So the bone property is a strong reference.

Weak reference The Bone can belong to a Dog. But we need to declare the belongsTo property as weak, otherwise we have a strong retain cycle (which means ARC is not going to release these object once we are done with them).

Important: In this scenario a Dog can exists without a Bone. And a Bone can exists without a Dog.

Unowned reference

Let's look at another example

class Person {
    var creditCard: CreditCard?
}

class CreditCard {
    unowned var owner: Person

    init(owner: Person) {
        self.owner = owner
    }
}

Again, Person can own a CreditCard, so it has a the owner property which is a strong reference to CreditCard.

However a CreditCard CANNOT exist without a person. Right? So inside CreditCard we want a property which will always be populated but we also want it to be weak.

Something like this

weak var owner: Person 
error: 'weak' variable should have optional type 'Person?'

However a weak property must be declared as Optional so we use the unowned which means:

I want a weak reference and it will always be populated.

like image 191
Luca Angeletti Avatar answered Dec 05 '22 12:12

Luca Angeletti