2014-10-09 73 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]

相關問題