ARC,通过被捕获的自我在块和参考周期中的ivars

我正在纯iOS5 / ARC环境中工作,所以我可以根据需要使用__weak引用。 在许多情况下,我都会在一个块中引用ivars,其中最引人注目的就是animation块,它们可以移动视图,这是我的视图控制器类的属性。

我的问题:

在一个块中最简单的使用ivars,我创build一个参考周期? 每次我写一个块来处理包含对象的实例variables时,是否需要使用__weak self / strong self技巧?

我一直在重新审视2011年WWDC会议#322(Objective-C的深度进展),以了解关于“通过被捕获的自我的参考周期”在时间索引25:03开始的3分钟片段的细微差别。 对我而言,这意味着任何一个块中的ivars的使用都应该被该段中描述的弱自我/强自我设置所保护。

在视图控制器上的下面的示例方法,是我做的animation的典型。

在openIris块中,像我一样引用ivars“_topView”和“_bottomView”是错误的吗?

我应该总是在块之前设置一个__weak引用,然后在块内部强引用刚刚设置的弱引用,然后通过块内的强引用访问ivars?

从WWDC会话中,我明白,在一个块中引用ivars实际上是创build了一个引用这些ivars隐含的隐含的自我。

对我来说,这意味着在没有弱/强舞的情况下访问ivars是正确的,确实没有任何简单或微不足道的情况来确保没有循环。 还是我读到了一个不适用于简单情况的angular落案例,比如我的例子?

- (void)openIrisAnimated:(BOOL)animated { if (_isIrisOpened) { NSLog(@"Asked to open an already open iris."); return; // Bail } // Put the common work into a block. // Note: “_topView” and “_bottomView” are the backing ivars of // properties “topView” and “bottomView” void (^openIris)() = ^{ _topView.frame = CGRectMake(....); _bottomView.frame = CGRectMake(....); }; // Now do the actual opening of the iris, whether animated or not: if (animated) { [UIView animateWithDuration:0.70f animations:^{ openIris(); }]; } else { openIris(); } _irisOpened = YES; // Because we have now just opened it } 

下面是我将如何使用会话#322的指导重写openIris块,但我只是想知道是否所有类似的块都需要这个弱/强参考舞以确保正确性和稳定性:

 __weak MyClass *weakSelf = self; void (^openIris)() = ^{ MyClass *strongSelf = weakSelf; if (strongSelf) { strongSelf.topView.frame = CGRectMake(....); strongSelf.bottomView.frame = CGRectMake(....); } }; 

这实际上是必要的吗?

如果自我继续持有对块的引用(或自己拥有的东西),那么只有一个循环。 如果不是这样的话,那么这个区块的生命并不是由它所保留的自我决定的。

所以在你的例子中,你似乎很清楚。 animation块不需要参与弱/强的自我舞蹈。

要担心的情​​况就像addObserverForName:object:queue:usingBlock: 文档说,“该块由通知中心复制”。 在ARC下,这个词“复制”是一个红旗; 现在你需要采取措施,让你(呼叫者)不会泄漏。

编辑:另外,有时ARC本身会提醒你。 -[UIPageViewController setViewControllers:direction:animated:completion:]的完成块就是一个例子。 我绝不会怀疑,在这里使用self可能会导致一个保留周期,但是ARC警告说,为了以防万一,我做了一个弱小的舞蹈。