我有一个关于内存释放和阻止/关闭的问题。
以下是Swift方法
self!.dismissViewControllerAnimated(false, completion: {
println(self);
})
或目标C方法
[self dismissViewControllerAnimated:NO completion:^{
NSLog("%@",self);
}];
我真的很感激,如果有人能解释什么时候在上面的方法自我将被解除分配。是在完成块运行之后还是之前?我理解它由ARC照顾,但我想知道self是否在完成块中或之后获得释放消息。因此,如果我在完成块中进行一些小的清理(访问自己),是否安全/可接受?
答案 0 :(得分:6)
完全理解答案确实有两个不同的问题:
您可以将闭包视为另一种类型(在Swift中它们确实是这样)。每个闭包都会对其中引用的变量产生强大的所有权,包括self
。这可确保您永远不会引用已解除分配的变量。就像在任何其他对象中一样,当闭包被解除分配时,它会释放对其所有变量的所有权。
如果闭包是唯一强烈引用该变量的东西,则在解除闭包闭包时该变量将被释放。
简而言之,只要闭包仍在内存中,变量就会保留在内存中。
现在,理解这一点的第二部分是什么时候闭包被取消分配。您可以在变量中存储闭包:
func myMethod() {
var myClosure = {
println(self)
}
myClosure()
}
在这种情况下,闭包具有来自变量myClosure
的强引用,并且闭包具有对self
的强引用。只要myClosure
超出范围,即myMethod
退出时,它就会被取消分配。当发生这种情况时,自我将被释放。
您可能还有一个情况,比如在您的问题中,您将闭包传递给另一个方法。在这种情况下,传递闭包的方法是捕获对闭包的强引用。当该方法退出时,它将释放你的闭包,闭包将被解除分配,它将释放在其中捕获的所有变量。
有时需要定义一个不对变量拥有所有权的闭包。您这样做是为了避免循环引用。您可以在Apple的文档中阅读更多关于循环引用的内容以及如何防止它们here的内容。但是,重要的是要认识到,除非你付出明确的努力(和代码),闭包总是会捕获对其中引用的变量的强引用。
答案 1 :(得分:2)
在Swift中,在开发/调试并尝试理解操作的时间时,可以将以下内容添加到View Controller(或任何类),以跟踪实例是否或何时将要解除分配。
虽然这不会帮助您检测此处描述的“强参考周期”:
deinit {
println(__FUNCTION__, "\(self)")
}