【发布时间】:2011-11-04 15:19:47
【问题描述】:
我在纯 iOS5/ARC 环境中工作,所以我可以根据需要使用 __weak 引用。在许多情况下,我确实在块中引用 ivars,最值得注意的是,移动视图的动画块,例如,我的视图控制器类的属性。
我的问题:
在块中最简单的 ivars 使用中,我是在创建一个引用循环吗?我是否需要使用 __weak self / strong self 技术每次我编写一个操作包含对象的实例变量的块?
我一直在重新观看 2011 年 WWDC 会议 #322(Objective-C 深度改进),以了解从时间索引 25:03 开始的 3 分钟片段“通过捕获的自我进行参考循环”的细微差别。对我来说,这意味着块中任何 ivars 的使用都应该通过该部分中描述的弱自我/强自我设置来保护。
以下视图控制器上的示例方法是我所做的典型动画。
在openIris块中,像我一样引用ivars“_topView”和“_bottomView”是不是错了?
我是否应该始终在块之前设置对 self 的 __weak 引用,然后在块内对之前设置的弱引用设置强引用,然后通过块内的强引用访问 ivars?
从 WWDC 会议中,我了解到在块中引用 ivars 实际上是在创建对这些 ivars 所依赖的隐含自我的引用。
对我来说,这意味着确实没有任何简单或琐碎的情况可以在没有弱/强舞蹈以确保没有循环的情况下访问块中的 ivars 是正确的。或者我是否阅读了很多不适用于简单案例的极端案例,例如我的示例?
- (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
}
以下是我使用 Session #322 的指导重写 openIris 块的方法,但我只是想知道我的所有类似块是否都需要这种弱/强参考舞蹈来确保正确性和稳定性:
__weak MyClass *weakSelf = self;
void (^openIris)() = ^{
MyClass *strongSelf = weakSelf;
if (strongSelf) {
strongSelf.topView.frame = CGRectMake(....);
strongSelf.bottomView.frame = CGRectMake(....);
}
};
这真的有必要吗?
【问题讨论】:
标签: objective-c ios ios5 objective-c-blocks automatic-ref-counting