I am exploring Swift value types particularly structs to get a better understanding of it's uses in different scenario. I was amazed to see how enum can be used to build Binary Search Tree using indirect
which introduces a thin layer of reference semantics.
enum BinarySearchTree<T: Comparable> {
case empty
case leaf(T)
indirect case node(BinarySearchTree, T, BinarySearchTree)
}
Now coming to real question, what I am struggling to find is, what will happen to reference type inside a value type. How will the relationship work? like memory management, Object lifecycle.
For e.g.
class B {
var data: Int = 0
deinit {
print("deallocated!")
}
}
struct A {
var b = B()
}
In the above case, a value type holds a reference to a reference type.
deinit
will get called?A
will have reference to same instance of class B
or will they be different. Every struct A
copy will share the same reference to B
. Every new struct A
, created from scratch, will hold a completely new B
object.
The B.deint
will be called when there are zero strong references to it (e.g., your var b
is one of these strong references). For instance, if only A
values hold references to a given B
object then those will need to got out of scope to zero all references to this object (or their boxed copies be deallocated as well, but this might be a topic for another question.)
Code Design. If these all sounds too confusing and is blocking your app progress (with no real practical benefit so far), you might consider refactoring B
to a struct as well. For instance, even Apple recommends considering value types to design your model layer. This blog post might also help make up your mind.
You can test this in a playground:
class B {
var data: Int = 0
deinit {
print("deallocated!")
}
}
struct A {
var b = B()
}
var a1: A? = A()
var a2: A? = A()
var a3: A? = a1
// Do the two instances of struct A share the same instance of class B?
a1?.b === a2?.b // false
// Do copies of instances of struct A share the same instance of class B?
a1?.b === a3?.b // true
// When will deinit be called?
a1 = nil // Not yet, a3 still holds a strong reference to the shared instance of class B
a3 = nil // Now! There are no longer any strong references to the shared instance of class B, so it is deallocated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With