dealloc问题后的dispatch_after

时间:2014-10-09 06:48:13

标签: ios objective-c multithreading dealloc

在viewDidLoad中的MyViewController中,我只有一个调用:

- (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;
}

之后在代码中我弹出了这个视图控制器,所以没有dispatch_afterdealloc肯定会被执行。

问题:

1)在这种情况下是否会调用dealloc方法(当我们有dispatch_after时,应该在20秒内执行)?

2)此方法[self doSomeSimpleThings];将在dealloc之后执行吗?

修改

在发布这个问题之前我试过了,并且没有调用dealloc并认为这很奇怪,这就是我在这里提出这个问题的原因。

3 个答案:

答案 0 :(得分:2)

您当前的代码会创建一个保留周期,因为您在块中引用了self。您可以使用对self的弱引用来打破周期。这样您也不需要isNeedToExecute标志:

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

取消分配视图控制器blockSelf后,nil将无法执行doSomeSimpleThings

答案 1 :(得分:1)

  

1)在这种情况下会调用dealloc方法(当我们有   dispatch_after,应该在20秒内执行)?

在没有对该对象的强引用之后将调用

dealloc。该块具有对该对象的强引用。 dispatch_after保持阻止直到它运行。因此,在块运行20秒后,将不再有强引用,并且可以释放对象(dealloc调用)。

  

2)将此方法[self doSomeSimpleThings];之后执行   的dealloc?

这是倒退的。实际上,当调用dealloc时,块(包含[self doSomeSimpleThings])运行时确定。所以答案是否定的,根据定义,因为dealloc无法运行,直到在这种情况下无法再运行[self doSomeSimpleThings]

答案 2 :(得分:0)

检查 dispatch_after 方法的定义。参数定义为

  

queue: - 提交块的队列。系统保留队列,直到块运行完成。此参数不能为NULL。

     

阻止: - < ......>此函数代表调用者执行Block_copy和Block_release。

所以基本上你的控制器对象将被这个队列保留,即使你已经设置它并且方法 doSomeSimpleThings 将被调用然后 dealloc