问题
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.
- When will
deinit
will get called? - Does every new struct instance of type
A
will have reference to same instance of classB
or will they be different. - What should I need to take care of or it is a code smell?
- Anything else?
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/43218486/reference-type-inside-value-type