Swift 将函数分配给 var 导致保留循环?
Swift assign function to var cause retain cycle?
我在 Swift Memory Management: Storing func in var 中遇到了类似的问题,但这并没有解决我的问题。
这是我的 class 定义:
class Test {
var block: (() -> Int)?
func returnInt() -> Int {
return 1
}
deinit {
print("Test deinit")
}
}
我尝试了两种给block
属性赋值的方法,得到了完全不同的结果。第二种方法没有引起retain circle,有点出乎意料:
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()
}
我在 Swift Memory Management: Storing func in var 中遇到了类似的问题,但这并没有解决我的问题。
这是我的 class 定义:
class Test {
var block: (() -> Int)?
func returnInt() -> Int {
return 1
}
deinit {
print("Test deinit")
}
}
我尝试了两种给block
属性赋值的方法,得到了完全不同的结果。第二种方法没有引起retain circle,有点出乎意料:
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()
}