块中的弱引用和保留周期 [英] Weak references in blocks and retain cycles

查看:103
本文介绍了块中的弱引用和保留周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个问题中,我询问了以下代码并保留了周期:

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 retains childObject
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆