我在一个纯iOS5 / ARC环境中工作,因此可以根据需要使用__weak引用。在许多情况下,尤其是移动视图的动画块(这些视图是视图控制器类的属性)中,我会在块中引用实例变量。
我的问题:
在最简单的ivar在block中的用法中,我是否会创建引用循环?每次编写操纵包含对象的实例变量的块时,我是否需要使用__weak self / strong self技术?
我一直在重新观看2011年WWDC Session#322 (Objective-C Advancements in Depth),以理解有关25:03时间索引处开始的有关“通过捕获的Self引用循环”的3分钟片段的微妙之处。对我来说,这意味着在块中使用ivar应该像在那个片段中描述的那样,以弱self /强self设置进行保护。
下面是视图控制器上的示例方法,典型的动画方法如下。
在openIris块中,像我这样引用ivar“_topView”和“_bottomView”是否有误?
我应该在块之前始终设置__weak引用,然后在块内设置强引用,以了解先前设置的弱引用,然后通过该强引用在块内访问ivars吗?
从WWDC会话中,我了解到在块中引用ivar实际上是创建对这些ivar所依附的隐含self的引用。
对我来说,这意味着没有任何简单或微不足道的情况是正确的,在没有进行弱/强跳舞以确保没有循环的情况下访问块中的ivar。或者我是否把一个不适用于简单情况(例如我的示例)的角落案例读得太多了?
- (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(....);
}
};
这么做真的有必要吗?