值类型中的引用类型
Reference type inside value type
我正在探索 Swift 值类型,尤其是结构,以便更好地了解它在不同场景中的用途。我很惊讶地看到枚举如何用于使用 indirect
构建二叉搜索树,它引入了一层薄薄的引用语义。
enum BinarySearchTree<T: Comparable> {
case empty
case leaf(T)
indirect case node(BinarySearchTree, T, BinarySearchTree)
}
现在谈到真正的问题,我正在努力寻找的是,值类型中的引用类型会发生什么。这种关系将如何运作?比如内存管理,对象生命周期。
例如
class B {
var data: Int = 0
deinit {
print("deallocated!")
}
}
struct A {
var b = B()
}
在上述情况下,值类型包含对引用类型的引用。
deinit
什么时候会接到电话?
A
类型的每个新结构实例是否都将引用 class B
的相同实例,或者它们是否不同。
- 我需要注意什么或者是代码味道?
- 还有什么吗?
每个结构 A
copy 将共享对 B
的 same 引用。从头开始创建的每个 new 结构 A
都将包含一个全新的 B
对象。
B.deint
将在 strong references 为零时调用(例如,您的 var b
是这些强引用之一).例如,如果只有 A
值持有对给定 B
对象的引用,那么这些值将需要超出范围以将对该对象的所有引用(或其 盒装副本 也被释放,但这可能是另一个问题的主题。)
代码设计。如果这些听起来太混乱并且阻碍了您的应用程序进展(到目前为止没有真正的实际好处),您也可以考虑将 B
重构为一个结构。例如,甚至 Apple recommends considering value types to design your model layer. This blog post 也可能有助于您下定决心。
您可以在 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.
我正在探索 Swift 值类型,尤其是结构,以便更好地了解它在不同场景中的用途。我很惊讶地看到枚举如何用于使用 indirect
构建二叉搜索树,它引入了一层薄薄的引用语义。
enum BinarySearchTree<T: Comparable> {
case empty
case leaf(T)
indirect case node(BinarySearchTree, T, BinarySearchTree)
}
现在谈到真正的问题,我正在努力寻找的是,值类型中的引用类型会发生什么。这种关系将如何运作?比如内存管理,对象生命周期。
例如
class B {
var data: Int = 0
deinit {
print("deallocated!")
}
}
struct A {
var b = B()
}
在上述情况下,值类型包含对引用类型的引用。
deinit
什么时候会接到电话?A
类型的每个新结构实例是否都将引用 classB
的相同实例,或者它们是否不同。- 我需要注意什么或者是代码味道?
- 还有什么吗?
每个结构 A
copy 将共享对 B
的 same 引用。从头开始创建的每个 new 结构 A
都将包含一个全新的 B
对象。
B.deint
将在 strong references 为零时调用(例如,您的 var b
是这些强引用之一).例如,如果只有 A
值持有对给定 B
对象的引用,那么这些值将需要超出范围以将对该对象的所有引用(或其 盒装副本 也被释放,但这可能是另一个问题的主题。)
代码设计。如果这些听起来太混乱并且阻碍了您的应用程序进展(到目前为止没有真正的实际好处),您也可以考虑将 B
重构为一个结构。例如,甚至 Apple recommends considering value types to design your model layer. This blog post 也可能有助于您下定决心。
您可以在 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.