Weak reference
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| class Person{
var name: String
var fruit: Fruit?
init(name: String) {
self.name = name
print ("Person init")
}
deinit {
print ("Person denit")
}
}
class Fruit{
var name: String
init(name: String) {
self.name = name
print ("Fruit init")
}
deinit {
print ("Fruit denit")
}
}
var person: Person? = Person(name: "john")
person!.fruit = Fruit(name: "apple")
person = nil //Prints "Person denit", "Fruit denit"
|
After line 28, the fruit object has one
strong reference on it (the property person.fruit), and the person object also has one
strong reference on it (the variable person).
At line 29, two things happen.
1. The person object has no reference on it and thus gets deallocated. It prints "Person deinit"
2. Since the person object is gone, the fruit object has no reference on it, and thus gets deallocated. It prints "Fruit deinit"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| class Person{
var name: String
var fruit: Fruit?
init(name: String) {
self.name = name
print ("Person init")
}
deinit {
print ("Person denit")
}
}
class Fruit{
var name: String
var person: Person?
init(name: String) {
self.name = name
print ("Fruit init")
}
deinit {
print ("Fruit denit")
}
}
var person: Person? = Person(name: "john")
var fruit: Fruit? = Fruit(name: "apple")
person!.fruit = fruit
fruit!.person = person
person = nil
fruit = nil //Nothing is deinitilised.
|
After line 32, the fruit object has two
strong references on it (the variable fruit, and the property person.fruit). Similarly the person object has two
strong references on it (the variable person, and the property fruit.person)
After line 34, both the fruit objects and the person objects have one
strong reference on it (the property person.fruit and fruit.person respectively). Hence nothing is deinitilised.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| class Person{
var name: String
weak var fruit: Fruit?
init(name: String) {
self.name = name
print ("Person init")
}
deinit {
print ("Person deinit")
}
}
class Fruit{
var name: String
var person: Person?
init(name: String) {
self.name = name
print ("Fruit init")
}
deinit {
print ("Fruit deinit")
}
}
var person: Person? = Person(name: "john")
var fruit: Fruit? = Fruit(name: "apple")
person!.fruit = fruit
fruit!.person = person
fruit = nil //Prints "Fruit deinit"
|
After line 32, the fruit object has one
strong reference (the variable fruit) and one
weak reference (the property person.fruit)
At line 33, the strong reference is broken, and there is only one weak reference left, which can't stop the object being deinitialised.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| class Person{
var name: String
weak var fruit: Fruit?
init(name: String) {
self.name = name
print ("Person init")
}
deinit {
print ("Person deinit")
}
}
class Fruit{
var name: String
var person: Person?
init(name: String) {
self.name = name
print ("Fruit init")
}
deinit {
print ("Fruit deinit")
}
}
var person: Person? = Person(name: "john")
var fruit: Fruit? = Fruit(name: "apple")
person!.fruit = fruit
fruit!.person = person
person = nil
fruit = nil //Prints "Fruit deinit, Person deinit"
|
After line 32, the fruit object has one
strong reference (the variable fruit) and one
weak reference (the property person.fruit). The person object two
strong references (the variable person and the property fruit.person)
At line 33, one strong reference on the person object is broken, but since there is another strong reference, object person can't be deallocated.
At line 34, the strong reference on the fruit object is broken, the fruit object is deallocated, thus breaking the other strong reference on the person object. Hence the person is deallocated.
Unowned reference
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| class Person{
var name: String
var fruit: Fruit?
init(_ name: String) {
self.name = name
print ("Person init")
}
deinit {
print ("Person deinit")
}
}
class Fruit{
var name: String
unowned var person: Person
init(_ name: String, person: Person) {
self.name = name
self.person = person
print ("Fruit init")
}
deinit {
print ("Fruit deinit")
}
}
var person: Person? = Person("john")
person!.fruit = Fruit("apple", person: person!)
person = nil //Prints "Person deinit, Fruit deinit"
|
After line 31, the person object has one
strong reference (var person), and one
unowned reference (property fruit.person).
At line 32, the strong reference on the person object is broken, and the person object is deallocated.
Note unowned cannot be used on optional type. (i.e. replacing
unowned by
weak in the above code causes compilation error)