Swift2 Swift将功能分配给var原因保留周期?

Swift2 Swift将功能分配给var原因保留周期?,swift2,retain-cycle,Swift2,Retain Cycle,我在年遇到了一个类似的问题,但这并没有解决我的问题 以下是我的类定义: class Test { var block: (() -> Int)? func returnInt() -> Int { return 1 } deinit { print("Test deinit") } } 我尝试了两种方法将值赋给块属性,得到了完全不同的结果。第二种方法没有引起retain circle,这是非常意外的: va

我在年遇到了一个类似的问题,但这并没有解决我的问题

以下是我的类定义:

class Test {
    var block: (() -> Int)?

    func returnInt() -> Int {
        return 1
    }

    deinit {
        print("Test deinit")
    }
}
我尝试了两种方法将值赋给
属性,得到了完全不同的结果。第二种方法没有引起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术语中,所有捕获的局部变量都是
\uu 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
重新分配给其他对象,而只是让它超出范围,那么它的行为就像一个强引用循环,除非您在
中包含
[unowned t]或在
中包含
[weak t]。。。