2014-10-09 44 views
0

在MyViewController在viewDidLoad中我只有一个电话:dispatch_after

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

你为什么不尝试,找出?你的问题真的是“如果我运行这个代码,会发生什么?” – borrrden 2014-10-09 06:55:20

+0

我会* *疑实例将作为您引用'dispatch_async()'块内'self'被保留,所以代码会被调用。你需要用不同的方法设置'isNeedToExecute'(比如'viewDidDisappear')。 – Droppy 2014-10-09 07:05:27

+0

1. doSomeSimpleThings在dealloc后不会调用。 2.只有当您的MyViewController将从堆栈中移除时,dealloc才会调用。所以在你的情况下,它不应该打电话。 – 2014-10-09 07:12:14

回答

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]; 
}); 

您的视图控制器blockSelfnildoSomeSimpleThings不会被执行的释放后。

+0

你能解释一下在保留周期中保留自己吗? – gabbler 2014-10-09 07:19:55

+0

@CarouselMin不是很明显吗? – Droppy 2014-10-09 07:20:28

+1

块保留所有在里面引用的变量。但你是对的,在这种情况下,这不是一个循环。参考资料一直保存到定时器启动。 – lassej 2014-10-09 07:22:03

0

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

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

block: - < ......>该函数代表调用者执行Block_copy和Block_release。

所以基本上你的控制器对象将通过此队列中保留,即使你已经POP操作它,方法doSomeSimpleThings将被调用,然后的dealloc

+1

你的结论是正确的,但真正的原因是,*块*保留'self'。 – 2014-10-09 07:14:46

1

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

dealloc将在没有对该对象的强引用之后被调用。该块对该对象具有强烈的参考。 dispatch_after保持该块直到它运行。所以在20秒后,块运行后,将不会有更强的引用,并且可以释放对象(调用dealloc)。

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

这是倒退。事实上,当dealloc被称为在块(含有[self doSomeSimpleThings])时由下式确定运行。因此,答案是否定的,那种定义,因为dealloc不能运行,直到它不再可能在这种情况下运行[self doSomeSimpleThings]

相关问题