调度到对象拥有的队列是否会保留该对象?

时间:2013-06-25 19:49:17

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

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

在这种情况下,块self会保留self,因为块块内没有dispatch_async()引用,但仅作为{{1}的参数}?

2 个答案:

答案 0 :(得分:2)

好的,所以苹果文档声明

  

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

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

感谢@Wain指出我在上一个版本的答案中的错误。

答案 1 :(得分:0)

不,如果该块既没有(a)对self的任何明确引用,也不会保留self;也不是(b)通过引用self的任何实例变量生成的对self的任何隐式引用。调用self.queuedispatch_async的存在不会导致它被保留。这就是重要的内部。

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

@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,您将看到视图控制器保留到块完成之后。