关于弱引用和无主引用,其区别主要是在于:
1.弱引用用于解决Optional值的引起的循环引用。
2.无主引用用于解决非Optional值引起的循环引用。
3.个人以为,弱引用可用下图表示:
4.无主引用可用如下图表示:
若将上面的代码修改如下,程序会直接崩溃:
class MyClassFive{
unowned var cls:MyClassSix
init(param:MyClassSix){
cls = param
}
deinit{
print("ClassFive deinit")
}
}
class MyClassSix{
var cls:MyClassFive?
deinit{
print("ClassSix deinit")
}
}
var obj6:MyClassSix? = MyClassSix()
var obj5:MyClassFive? = MyClassFive(param: obj6!)
obj6?.cls = obj5
obj6=nil
obj5?.cls
上面所举的例子满足了两种情况,一种是两类实例引用的属性都是Optional值的时候使用weak来解决循环引用,一种是两类实例有一个为非Optional值的时候使用unowned来解决循环引用,然而还有第三种情况,两类实例引用的属性都为非Optional值的时候,可以使用无主引用与隐式拆包结合的方式来解决,这也是无主引用最大的应用之处,示例如下:
class MyClassSeven{
unowned var cls:MyClassEight
init(param:MyClassEight){
cls = param
}
deinit{
print("ClassSeven deinit")
}
}
class MyClassEight{
var cls:MyClassSeven!
init(){
cls = MyClassSeven(param:self)
}
deinit{
print("ClassEight deinit")
}
}
var obj7:MyClassEight? = MyClassEight()
obj7=nil
除了在两个类实例间会产生循环引用,在闭包中,也可能出现循环引用,当某个类中包含一个闭包属性,同时这个闭包属性中又使用了类实例,则会产生循环引用,示例如下:
class MyClassNine {
var name:String = "HS"
lazy var closure:()->Void = {
//闭包中使用引用值会使引用+1
print(self.name)
}
deinit{
print("ClassNine deinit")
}
}
var obj9:MyClassNine? = MyClassNine()
obj9?.closure()
obj9=nil
//不会打印析构信息
Swift中提供了闭包的捕获列表来对引用类型进行弱引用或者无主引用的转换:
class MyClassNine {
var name:String = "HS"
lazy var closure:()->Void = {
[unowned self]()->Void in
print(self.name)
}
deinit{
print("ClassNine deinit")
}
}
var obj9:MyClassNine? = MyClassNine()
obj9?.closure()
obj9=nil
捕获列表以中括号标识,多个捕获参数则使用逗号分隔。