【问题标题】:When is self deallocated while dismissing view controller关闭视图控制器时何时自行释放
【发布时间】:2014-07-23 00:48:15
【问题描述】:

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

下面是Swift方法

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

或者客观C方法

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

如果有人能解释在上述方法中何时 self 将被释放,我将不胜感激。是在完成块运行之后还是之前?我了解它由 ARC 处理,但我想知道 self 是否在完成块中或之后收到释放消息。因此,如果我在完成块(访问自我)中进行一些小的清理,那是否安全/可接受?

【问题讨论】:

  • 肯定是在解雇完成之后。虽然不是必要之后立即。
  • 如果你在闭包内引用self,闭包将保留对已关闭视图控制器的引用。将清理放在那里的行为应该保证您的视图控制器在执行闭包之前不会被释放。
  • 看这个link 这是一本关于闭包捕获的好书。

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


【解决方案1】:

确实有两个独立的问题可以完全理解答案:

1。闭包内引用的变量何时发布?

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

如果闭包是唯一对该变量具有强引用的对象,则在释放闭包时该变量将被释放。

所以简而言之,只要闭包还在内存中,变量就会留在内存中。

2。闭包何时解除分配?

现在需要理解的第二部分是闭包何时解除分配。您可以将闭包存储在变量中:

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

在这种情况下,闭包具有来自其变量myClosure 的强引用,并且闭包具有对self 的强引用。一旦myClosure 超出范围,即当myMethod 退出时,它将被释放。发生这种情况时,self 将被释放。

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

例外

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

【讨论】:

  • 循环引用又名“强引用循环”
  • 闭包有一个来自其变量myClosure的强引用什么?你是说myMethod,有一个使用var myClosure定义的闭包,然后使用myClosure()运行闭包,它对self有很强的引用,一旦myMethod被释放,它就会被释放?好的,但是你为什么不需要[weak self] 呢?
【解决方案2】:

在 Swift 中,在开发/调试和尝试了解操作的时间安排时,您可以将以下内容添加到您的视图控制器(或任何类)中,以跟踪实例是否或何时即将被释放。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-31
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多