Search code examples
iosobjective-cmultithreadingdealloc

dispatch_after after dealloc issue


In MyViewController in viewDidLoad I have only one call:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.isNeedToExecute = YES;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(20 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self doSomeSimpleThings];
            });
}

-(void)doSomeSimpleThings {
      if (!self.isNeedToExecute) {
           return;
      }
      // do some simple actions
}

- (void)dealloc {
     self.isNeedToExecute = NO;
}

After that in code I pop this view controller, so without dispatch_after the dealloc would be executed for sure.

The questions:

1) will the dealloc method be called in this case (when we have dispatch_after, that should be executed in 20 seconds)?

2) will this method [self doSomeSimpleThings]; be executed after dealloc?

Edit:

I tried it before posting this question, and dealloc wasn't called and thought that it was strange, that's why I asked this question here.


Solution

  • Your current code creates a retain cycle because you reference self inside the block. You can break the cycle by using a weak reference to self. This way you also don't need the isNeedToExecute flag:

    __weak id blockSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(20 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
      [blockSelf doSomeSimpleThings];
    });
    

    After deallocation of your view controller blockSelf is nil and doSomeSimpleThings won't be executed.