考虑以下代码:

class Foo
{

}

func foo() -> (Void -> Foo)
{
    var foo = Foo()
    return { foo }
}

var fooGen = foo()

现在,每当我调用fooGen时,都会获取存储的Foo实例。但是,存储foo的确切位置是什么?它在烟囱里吗?如果是这样,那它的一生是什么?

最佳答案

类和闭包都是引用类型。

var foo = Foo()

在堆上创建一个Foo对象,并存储一个
(强)在本地堆栈变量foo中引用该对象。
return { foo }

创建一个捕获foo的闭包,以便闭包保持
对该对象的另一个(强)引用。
从函数返回时,局部变量foo超出范围,
对于这一点,只有一个来自结束的参考仍然存在。
var fooGen = foo()

引用返回的闭包
fooGen对象的引用):
fooGen -> closure -> Foo object

因此只要存在Foo引用,对象就存在。
(假设没有创建其他强引用)。
演示:
class Foo
{
    deinit {
        println("deinit")
    }
}

func foo() -> (Void -> Foo)
{
    var foo = Foo()
    return { foo }
}

if true {
    var fooGen = foo()
    println("foo")
}

println("done")

输出:

德尼特
完成
当程序控制离开Foo范围时,对象将被销毁。

10-07 19:13
查看更多