何时在解除视图控制器时自行解除分配

时间:2014-07-23 00:48:15

标签: ios objective-c swift automatic-ref-counting objective-c-blocks

我有一个关于内存释放和阻止/关闭的问题。

以下是Swift方法

    self!.dismissViewControllerAnimated(false, completion: {
        println(self);
     })

或目标C方法

   [self dismissViewControllerAnimated:NO completion:^{
       NSLog("%@",self);
   }];

我真的很感激,如果有人能解释什么时候在上面的方法自我将被解除分配。是在完成块运行之后还是之前?我理解它由ARC照顾,但我想知道self是否在完成块中或之后获得释放消息。因此,如果我在完成块中进行一些小的清理(访问自己),是否安全/可接受?

2 个答案:

答案 0 :(得分:6)

完全理解答案确实有两个不同的问题:

1。何时在闭包内引用变量?

您可以将闭包视为另一种类型(在Swift中它们确实是这样)。每个闭包都会对其中引用的变量产生强大的所有权,包括self。这可确保您永远不会引用已解除分配的变量。就像在任何其他对象中一样,当闭包被解除分配时,它会释放对其所有变量的所有权。

如果闭包是唯一强烈引用该变量的东西,则在解除闭包闭包时该变量将被释放。

简而言之,只要闭包仍在内存中,变量就会保留在内存中。

2。何时解除分配?

现在,理解这一点的第二部分是什么时候闭包被取消分配。您可以在变量中存储闭包:

func myMethod() {
    var myClosure = {
        println(self)
    }
    myClosure()
}

在这种情况下,闭包具有来自变量myClosure的强引用,并且闭包具有对self的强引用。只要myClosure超出范围,即myMethod退出时,它就会被取消分配。当发生这种情况时,自我将被释放。

您可能还有一个情况,比如在您的问题中,您将闭包传递给另一个方法。在这种情况下,传递闭包的方法是捕获对闭包的强引用。当该方法退出时,它将释放你的闭包,闭包将被解除分配,它将释放在其中捕获的所有变量。

例外

有时需要定义一个对变量拥有所有权的闭包。您这样做是为了避免循环引用。您可以在Apple的文档中阅读更多关于循环引用的内容以及如何防止它们here的内容。但是,重要的是要认识到,除非你付出明确的努力(和代码),闭包总是会捕获对其中引用的变量的强引用。

答案 1 :(得分:2)

在Swift中,在开发/调试并尝试理解操作的时间时,可以将以下内容添加到View Controller(或任何类),以跟踪实例是否或何时将要解除分配。

虽然这不会帮助您检测此处描述的“强参考周期”:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

deinit {
    println(__FUNCTION__, "\(self)")
}