【问题标题】:ARC capturing self... block inside a block and reference being released before executionARC 在块内捕获 self... 块并在执行前释放引用
【发布时间】:2013-02-02 23:19:53
【问题描述】:

我有这个问题:块中的块。

  self.createStuff = ^ (NSString *text) {       
        self.post.onCompletion = ^(NSURLResponse *response, NSData *data, NSError *error){
                [self doStuff];  // error here
        };
        [self doMoreStuff];  // error here
  };

我会在 [self doStuff] 和 [self doMoreStuff] 中出现错误。错误是在此块中强烈捕获“自我”可能导致保留周期

说起来简单,加个就行了

id mySelf = self; 

在第一个块之前并使用 mySelf。

不。这不会解决我的问题,仅仅是因为 mySelf 是一种 id 不会给我第二行需要的 post 属性。所以我需要像这样声明它

MyClass *mySelf = self;

把它变成这样:

MyClass *mySelf = self;

  self.createStuff = ^ (NSString *text) {       
        mySelf.post.onCompletion = ^(NSURLResponse *response, NSData *data, NSError *error){
                [self doStuff];  // error here
        };
        [mySelf doMoreStuff];  
  };

好的,你说,现在 self.post.onCompletion 行和 doMoreStuff 不再抱怨了,但是我们在 onCompletion 内部有了另一个 self... 因为这是块中的块。我可以重复创建另一个弱引用的过程,例如,这必须是对弱引用的弱引用

MyClass *internalMyself = mySelf;

并使用

   [internalMyself doStuff];

在我看来,这似乎是一种非常可悲的方法,而且当此方法运行时,应用程序会挂起。在方法执行之前,像引用之类的东西正在被释放......

我该如何解决这个字谜?

谢谢。


注意:正在编译到 iOS 6+

【问题讨论】:

  • 嗯,现在是我关掉 ARC 的时候了。
  • 拥有一个非 ARC 类和无数其他类 ARC 会更可悲。
  • @H2CO3:这与 ARC 无关。保留周期也发生在 MRC 中。

标签: iphone ios ipad objective-c-blocks


【解决方案1】:

你已经很接近了。只需更换您的解决方案

MyClass *mySelf = self;

self.createStuff = ^ (NSString *text) {       
     mySelf.post.onCompletion = ^(NSURLResponse *response, NSData *data, NSError *error) {
          [self doStuff];  // error here
     };
     [mySelf doMoreStuff];  
};

__weak MyClass *mySelf = self;

self.createStuff = ^ (NSString *text) {       
     mySelf.post.onCompletion = ^(NSURLResponse *response, NSData *data, NSError *error) {
          [self doStuff];  // error here
     };
     [mySelf doMoreStuff];  
};

第一个解决方案的问题是mySelf 没有被指定为weak,所以它的所有权限定符隐含地是__strong (see LLVM's documentation)。我不确定为什么这会消除第一个块中的警告,但指定引用 __weak 将完全删除保留周期。

【讨论】:

  • __weak 是否适用于 iOS 6?此应用仅针对 iOS 6+ 进行编译。
  • __weak 所有权限定符适用于使用 ARC 编译的文件。因为您已经在使用 ARC,所以不会有什么不同。
  • __weak 仅适用于 iOS 5+。如果您需要在 ARC 上支持 iOS 4,则需要使用 __unsafe_unretained
  • [self doStuff] 怎么样,你不应该也用__weak self 来称呼它吗?据我了解,第一个block保留了我们的弱自我,而弱self在第二个self中保留了block,这意味着第一个块也保留了self。我错了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-05
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多