请考虑以下代码:
class Foo
{
}
func foo() -> (Void -> Foo)
{
var foo = Foo()
return { foo }
}
var fooGen = foo()
现在每当我致电fooGen
时,我都会收到存储的Foo
个实例。但究竟在哪里存储foo
?它在堆栈内吗?如果是这样,那么它的生命是什么?
答案 0 :(得分:5)
类和闭包都是引用类型。
var foo = Foo()
在堆上创建一个Foo
对象,并存储一个
(强)引用本地堆栈变量foo
中的该对象。
return { foo }
创建一个捕获foo
的闭包,以便闭包
另一个(强烈的)对该对象的引用。
从函数返回时,本地foo
变量超出范围,
只有一个关闭的参考仍然存在。
var fooGen = foo()
使fooGen
引用返回的闭包(后者又有
对Foo
对象的引用:
fooGen -> closure -> Foo object
只要存在Foo
引用,fooGen
对象就存在
(假设没有创建额外的强引用)。
演示:
class Foo
{
deinit {
println("deinit")
}
}
func foo() -> (Void -> Foo)
{
var foo = Foo()
return { foo }
}
if true {
var fooGen = foo()
println("foo")
}
println("done")
输出:
foo deinit done
当程序控制离开fooGen
范围时,对象将被销毁。