問題描述
我在純 iOS5/ARC 環境中工作,所以我可以根據需要使用 __weak 引用.在許多情況下,我確實在塊中引用了 ivars,最值得注意的是,移動視圖的動畫塊,例如,我的視圖控制器類的屬性.
I’m working in a pure iOS5/ARC environment, so I can use __weak references as needed. I do reference ivars in a block in many situations, most notably, animation blocks that move views around, which are properties of say, my view controller class.
在一個塊中最簡單的 ivars 使用中,我是在創建一個引用循環嗎?我是否需要使用 __weak self/strong self 技術每次我編寫一個操作包含對象的實例變量的塊?
In the most trivial use of ivars in a block, am I creating a reference cycle? Do I need to use the __weak self / strong self technique everytime I write a block that manipulates instance variables of the containing object?
我一直在重新觀看 2011 年 WWDC 會議 #322(Objective-C 深度改進),以了解從時間索引 25:03 開始??的 3 分鐘片段通過捕獲的自我進行參考循環"的細微差別.對我來說,這意味著塊中任何 ivars 的使用都應該通過該部分中描述的弱自我/強自我設置來保護.
I’ve been re-watching the 2011 WWDC Session #322 (Objective-C Advancements in Depth) to understand the nuances regarding the 3 minute segment starting at time index 25:03 about "Reference Cycle Via Captured Self". To me, this implies any usage of ivars in a block should be safeguarded with the weak self / strong self setup as described in that segment.
以下視圖控制器上的示例方法是我所做的典型動畫.
The sample method below on a view controller, is typical of animations I do.
在openIris塊中,像我一樣引用ivars_topView"和_bottomView"是不是錯了?
In the openIris block, is it wrong to reference ivars "_topView" and "_bottomView" as I have?
我是否應該始終在塊之前設置對 self 的 __weak 引用,然后在塊內對之前設置的弱引用設置強引用,然后通過塊內的強引用訪問 ivars?
Should I always setup a __weak reference to self before the block, then a strong reference inside the block to the weak reference just setup prior, and then access the ivars through that strong reference within my block?
從 WWDC 會議中,我了解到在塊中引用 ivars 實際上是在創建對這些 ivars 所依賴的隱含自我的引用.
From the WWDC session, I understand that referencing ivars in a block is really creating a reference to the implied self that these ivars hang off of.
對我來說,這意味著真的沒有任何簡單或瑣碎的情況可以在沒有弱/強舞蹈以確保沒有循環的情況下訪問塊中的 ivars 是正確的.或者我是否閱讀了很多不適用于簡單案例的極端案例,例如我的示例?
To me, this implies that there really isn’t any simple or trivial case where it is correct to access ivars in a block without the weak/strong dance to ensure no cycles. Or am I reading to much into a corner case that doesn’t apply to simple cases, such as my example?
- (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 塊的方法,但我只是想知道我的所有類似塊是否都需要這種弱/強參考舞蹈來確保正確性和穩定性:
Here’s how I’d re-write the openIris block piece using the guidance from Session #322, but I’m just wondering if all my similar blocks require this weak/strong reference dance to ensure correctness and stability:
__weak MyClass *weakSelf = self;
void (^openIris)() = ^{
MyClass *strongSelf = weakSelf;
if (strongSelf) {
strongSelf.topView.frame = CGRectMake(....);
strongSelf.bottomView.frame = CGRectMake(....);
}
};
這真的有必要嗎?
推薦答案
這里只有一個循環,如果 self 然后繼續持有對塊的引用(或自己擁有的東西).如果不是,你最好去,因為塊的生命周期不是由它保留的 self 決定的.
There is only a cycle here if self then goes on to hold a reference to the block (or something owned by self). If not you're good to go as the lifetime of the block is not dictated by the self it retained.
因此,在您的特定示例中,您似乎很清楚.動畫塊不需要參與弱/強自舞.
So in your particular example, you seem to be in the clear. Animation blocks don't need to participate in the weak/strong self dance.
這篇關于ARC,塊中的 ivars 和通過捕獲的自我的參考周期的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!