块中的弱引用和保留周期 [英] Weak references in blocks and retain cycles
问题描述
在这个问题中,我询问了以下代码并保留了周期:
In this question, I asked about the following code and retain cycles:
__weak Cell *weakSelf = self;
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
UIImage *image = /* render some image */
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[weakSelf setImageViewImage:image];
}];
}];
[self.renderQueue addOperation:op];
所有答案都说没有必要使用弱引用,因为此代码不会导致保留周期。但是,在尝试更多代码时,以下操作会导致保留周期(如果我不使用弱引用,则当前视图控制器不会被释放)
All answers state that using a weak reference here was not necessary, since this code does not result in a retain cycle. However, while experimenting with some more code, the following does result in a retain cycle (if I don't use a weak reference, the current view controller is not deallocated)
//__weak ViewController *weakSelf = self;
MBItem *close = [[MBItem alloc] initWithBlock:^{
[self dismissModalWithDefaultAnimation:NO];
}];
NSMutableArray *items = [[NSMutableArray alloc] initWithObjects:close, nil];
[self.childObject setItems:items];
为什么第二个会导致保留周期而不是第一个?
Why would the second one result in a retain cycle but not the first one?
推荐答案
如果您不使用 __ weak
,您的旧代码会创建此保留周期 :
Your old code creates this retain cycle if you don't use __weak
:
-
(NSBlockOperation *)op
保留外部块 - 外部块保留
self
(如果你没有使用__ weak
) -
self
保留(NSOperationQueue *)renderQueue
-
(NSOperationQueue *)renderQueue
保留(NSBlockOperation *)op
(NSBlockOperation *)op
retains the outer block- The outer block retains
self
(if you're not using__weak
) self
retains(NSOperationQueue *)renderQueue
(NSOperationQueue *)renderQueue
retains(NSBlockOperation *)op
除非其中一个链接断开,否则不能解除分配该周期中的任何对象。但是你向我们展示的代码确实打破了保留周期。当 op
完成执行时, renderQueue
将其释放,从而打破保留周期。
None of the objects in that cycle can be deallocated unless one of those links is broken. But the code you showed us does break the retain cycle. When op
finishes executing, renderQueue
releases it, breaking the retain cycle.
我怀疑你的新代码创建了这个保留周期:
I suspect that your new code creates this retain cycle:
-
(MBItem *)close
保留该块 - 该块保留
self
-
self
保留childObject
-
childObject
保留(NSMutableArray *)商品
-
(NSMutableArray *)商品
保留(MBItem *)关闭
(MBItem *)close
retains the block- The block retains
self
self
retainschildObject
childObject
retains(NSMutableArray *)items
(NSMutableArray *)items
retains(MBItem *)close
如果没有碰巧打破其中一个链接,循环中的所有对象都不能被释放。您没有向我们展示任何打破保留周期的代码。如果没有明确破坏它的事件(例如清除 childObject.items
),那么你需要使用 __ weak
打破保留周期。
If nothing happens to break one of those links, none of the objects in the cycle can be deallocated. You haven't shown us any code that breaks the retain cycle. If there is no event that explicitly breaks it (for example by clearing out childObject.items
), then you need to use __weak
to break the retain cycle.
这篇关于块中的弱引用和保留周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!