0

我试图掌握如何识别何时可能有强大的保留周期并需要我使用[weak/unowned self]. 我因不必要的使用[weak/unowned self]而被烧毁,并且在给我机会使用它之前立即释放了自我。

例如,下面是self闭包中引用的异步网络调用。由于网络调用是在没有将调用本身存储到变量中的情况下进行的,这里会发生内存泄漏吗?

NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) {
  (data, response, error) in
  self.data = data
)

这是另一个使用 NSNotificationCenter 的示例,稍后可以异步进行调用:

 NSNotificationCenter.defaultCenter().addObserverForName(
        UIApplicationSignificantTimeChangeNotification, object: nil, queue: nil) {
            [unowned self] _ in
            self.refresh()
    }

我的问题是在什么情况下可能会出现强保留周期?如果我在闭包中进行引用 self 的异步调用或静态调用,这是否使其成为候选对象[weak/unowned self]?感谢您对此有所了解。

4

2 回答 2

1

简而言之:

保留周期可能在两种情况下发生。

情况1:

当两个实例相互具有强引用时。您必须通过将其中一个标记为弱来解决此问题。

案例2:(与您的问题有关)

如果您将闭包分配给类实例的属性,并且该闭包的主体捕获该实例。

在您的两个示例中,根本不需要使用弱自我,也不需要使用NSNotificationCenterNSURLSession实例的属性。(或者在其他意义上,你没有对它们的强引用)

检查这个我必须使用弱自我的例子:

[self.mm_drawerController setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) {

    if (drawerSide == MMDrawerSideRight && percentVisible == 1.0) {
        [weakself showOverlayBgWithCloseButton:YES];
    }
    else{

        [weakself hideOverlayBg];
    }
}];

我有一个强烈的参考mm_drawerController,我给它分配了一个闭包,对吗?在这个闭包中,我想捕捉自我。所以闭包会对 self 有很强的引用!!这是一场灾难。在这种情况下,您将有一个保留周期。要打破这个循环,请在闭包内使用弱自我。

于 2016-05-15T14:07:10.077 回答
1

保留循环是两个对象相互具有强引用的情况。

在此处输入图像描述

您正在使用静态变量 NSURLSession.sharedSession() 和 NSNotificationCenter.defaultCenter() 并且您可能还记得:

单例对象提供了对其类资源的全局访问点……您可以通过工厂方法从单例类获取全局实例。该类在第一次被请求时懒惰地创建它的唯一实例,然后确保不能创建其他实例。单例类还可以防止调用者复制、保留或释放实例。

https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Singleton.html

您的“自我”实例(与其他实例一样)也没有对单例对象及其闭包的强引用,这就是为什么您不必担心您的情况下的保留周期。

查看这篇精彩的文章了解更多详情: https ://digitalleaves.com/blog/2015/05/demystifying-retain-cycles-in-arc/

于 2016-05-15T14:07:28.040 回答