Swift将var函数赋值给var导致保留周期?
问题描述:
我遇到了Swift Memory Management: Storing func in var中的类似问题,但这并未解决我的问题。Swift将var函数赋值给var导致保留周期?
这里是我的类定义:
class Test {
var block: (() -> Int)?
func returnInt() -> Int {
return 1
}
deinit {
print("Test deinit")
}
}
我尝试了两种方式来分配价值block
财产,得到了完全不同的结果。第二种方法没有造成保留圈,这是相当出人意料:
var t = Test()
// This will lead to retain cycle
// t.block = t.returnInt
// I thought this will also lead to retain cycle but actually didn't
t.block = {
return t.returnInt()
}
t = Test()
在我看来,变量t
由block
而block
是t
属性捕获,所以任何人都可以解释为什么没有一个保留周期?
答
在Swift中,所有捕获的变量都通过引用捕获(Apple Blocks术语中,所有捕获的本地变量都是__block
)。因此块内的t
与块外的t
共享;该块不保存t
的独立副本。
本来,有在所述第二情况下的保留周期太,作为块保持参考的t
此共享副本,并t
指向第一Test
对象,并且该Test
对象的block
属性指向该块。但是,当您重新分配共享变量t
(在块的内部和外部都可见)时,会中断保留周期,因为t
不再指向第一个Test
对象。
在第一种情况中,t
被有效地捕获值,这是因为t
在表达t.returnInt
立即评估,而不是被捕捉为在一个块中的变量。因此,在块之后重新分配t
对块没有影响,并且不会中断保留周期。所以,你能想到的
t.block = t.returnInt
为一种像
let tmp = t
t.block = {
return tmp.returnInt()
}
有趣的是,如果你不重新分配't'到别的东西,只是让它掉下来的范围,但它像一个强参考周期,除非您在''中包含'[无主t]'或''中的[弱t] – Rob