块中的强引用

时间:2014-02-28 09:15:57

标签: ios iphone

我知道阻止的最佳做法就是那样

__weak SomeObjectClass *weakSelf = self;

SomeBlockType someBlock = ^{
    SomeObjectClass *strongSelf = weakSelf;
    if (strongSelf == nil) {
        // The original self doesn't exist anymore.
        // Ignore, notify or otherwise handle this case.
    }
    [self someMethod];
};

我理解使用 weakSelf 用于防止保留周期,并且在weakSelf可能为零的情况下使用 strongSelf 。 但我只是想知道使用 strongSelf 会再次导致保留周期,因为块捕获并保留strongSelf和strongSelf也是自我的指针。 有人可以给我一个解释,谢谢。

3 个答案:

答案 0 :(得分:1)

问问自己:strongSelf存在多久了?

strongSelf仅在块执行时才存在。所以基本上,它在someMethod正在执行时拥有强大的参考,而不再是。

我认为你的意思是

[strongSelf someMethod];

而不是

[self someMethod];

因为前者强烈引用 strongSelf (等于self),而块执行,而后者将强烈引用 self ,阻止存在

答案 1 :(得分:0)

来自documentation

  

您可以使用生命周期限定符来避免强引用周期。对于   例如,通常如果你有一个排列在一个对象的图形   亲子等级和父母需要引用他们的孩子和   反之亦然,那么你就使父母与子女的关系变得强大   孩子与父母的关系薄弱。其他情况可能更多   微妙的,特别是当它们涉及块状物体时。*

     

在手动引用计数模式下,__ _block id x;有没有效果   保留x。在ARC模式下,__block id x;默认为保留x(只是   像所有其他值一样)。获得手动引用计数模式   在ARC下的行为,你可以使用__unsafe_unretained __block id x;。   正如名称__unsafe_unretained暗示的那样,有一个   非保留变量是危险的(因为它可以悬挂)并且是   因此气馁。两个更好的选择是使用__weak(如果   你不需要支持iOS 4或OS X v10.6),或者设置__block   值为零以打破保留周期。

更多documentation

  

如果你需要在一个块中捕获self,比如在定义一个时   回调块,考虑内存管理很重要   影响。

     

Blocks保持对任何捕获对象的强引用,包括   自我,这意味着很容易得到一个强大的参考   周期

至于你的例子 - 那里没有保留周期,因为 CouchDeveloper 表示,因为块只会在执行时保持对self的引用。但是,无论你的__weak声明,如果我们将代码更改为:

__weak SomeObjectClass *weakSelf = self;

self.someBlock = ^{
    SomeObjectClass *strongSelf = weakSelf;
    if (strongSelf == nil) {
        // The original self doesn't exist anymore.
        // Ignore, notify or otherwise handle this case.
    }
    [self someMethod];
};

现在我们有保留周期 - 我们引用了块和内部块我们引用了self。为避免这种情况,您应该使用__weak方法:

__weak SomeObjectClass *weakSelf = self;

self.someBlock = ^{
    SomeObjectClass *strongSelf = weakSelf;
    if (strongSelf == nil) {
        // The original self doesn't exist anymore.
        // Ignore, notify or otherwise handle this case.
    } else {
       [strongSelf someMethod];
    }
};

更多文章: https://coderwall.com/p/vaj4tg

http://teohm.com/blog/2012/09/03/breaking-arc-retain-cycle-in-objective-c-blocks/

答案 2 :(得分:-1)

首先,你必须了解strongSelf的生命周期,它只存在于someBlock中,在someBlock完成后,strongSelf引用的对象将被释放。 当someBlock翻译成MRR时会喜欢这样:

^{
  SomeObjectClass *strongSelf = [weakSelf retain];
  if (strongSelf == nil) {
  // The original self doesn't exist anymore.
  // Ignore, notify or otherwise handle this case.
  }
  [self someMethod];
  [strongSelf release];
};