質問

Suppose I have a simple call dispatch_async(self.queue, ^{ /* Empty */ }), where self.queue is a queue created previously.

Does self get retained by the Block in this case, given that there is no self reference inside the block, but only as a parameter for dispatch_async()?

役に立ちましたか?

解決 2

No, self will not get retained if the block has neither (a) any explicit references to self; nor (b) any implicit references to self that are generated by referencing any instance variables of self. The presence of self.queue in the invocation of dispatch_async will not cause it to be retained. It's what inside the block that matters.

This is quite easy to demonstrate. Imagine a view controller whose implementation looks like:

@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

If you push to this view controller's scene, and then immediately press the "back" button to pop it off, you'll see the view controller immediately be deallocated, and the block will continue to execute. But if you add a class instance variable or property to the block, you'll see the view controller retained until after the block completes.

他のヒント

Ok, so apple docs states that

The queue is retained by the system until the block has run to completion.

So the queue will be retained by the system until the block completes the execution, but the self won't be retained in this case.

Thanks to @Wain for pointing out my mistake in the previous version of this answer.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top