【问题标题】:Does dispatching to a queue that's owned by an object retain that object? [duplicate]分派到对象拥有的队列是否会保留该对象? [复制]
【发布时间】:2013-06-25 19:49:17
【问题描述】:

假设我有一个简单的呼叫dispatch_async(self.queue, ^{ /* Empty */ }),其中self.queue 是先前创建的队列。

在这种情况下,self 是否会被块保留,因为在块内没有 self 引用,而只是作为 dispatch_async() 的参数?

【问题讨论】:

  • 什么是“自我被保留以阻止”是什么意思?你的意思是,“self 是否因为我将它的队列传递给 dispatch_async 而被保留?”

标签: objective-c-blocks grand-central-dispatch retain reference-counting


【解决方案1】:

好的,所以苹果文档声明

队列由系统保留,直到块运行到 完成。

所以队列将被系统保留,直到块完成执行,但在这种情况下不会保留self

感谢@Wain 指出我在此答案的先前版本中的错误。

【讨论】:

  • 保留队列如何导致保留self
  • 我可能在这种情况下使用了错误的词,self 在队列被释放之前不能被释放/释放。如果我错了,请纠正我。
  • 当然可以。没有self,队列可以继续存在。系统是维护对队列的“持久”引用的东西。
  • 天哪,我简直不敢相信我刚才说的话,@Wain 你完全正确。我编辑了我的分析器。
  • 嗯,那好吧。为什么块内使用的其他属性会导致保留自我?因为他们“没有自我就不能存在?”
【解决方案2】:

不,如果块既没有(a)对self 的任何显式引用,self 将不会被保留;也不 (b) 通过引用 self 的任何实例变量生成的对 self 的任何隐式引用。在调用dispatch_async 时出现self.queue 不会导致它被保留。重要的是块内的内容。

这很容易演示。想象一个视图控制器,其实现如下:

@interface SecondViewController ()
@property (nonatomic, strong) dispatch_queue_t queue;
@end

@implementation SecondViewController

- (void)dealloc
{
    NSLog(@"%s", __FUNCTION__);
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.queue = dispatch_queue_create("com.stackoverflow.17306228", 0);

    void (^block)(void) = ^(void){
        sleep(10);

        NSLog(@"%s", __FUNCTION__);
    };

    dispatch_async(self.queue, block);
}

@end

如果你推到这个视图控制器的场景,然后立即按下“返回”按钮将其弹出,你会看到视图控制器立即被释放,块将继续执行。但是如果你将一个类实例变量或属性添加到block,你会看到视图控制器一直保留到块完成之后。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    相关资源
    最近更新 更多