2011-08-17 14 views
16

我需要一種保存的方式來說:「iOS,我希望這個方法被執行a.s.a.p.,但不是在這個運行循環迭代中,最早在下一個,但請不要在這個中,謝謝。如何調用方法a.s.a.p.但最早在下一次運行循環迭代中?

現在我總是在做這樣的:

[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0]; 
[self doSomeOtherThings]; 

隨着該-doSomeOtherThings將總是先 -doSomethingInNextRunLoop進行假設。

文檔說:

指定爲0的延遲並不一定導致選擇是 立即執行。選擇器仍在線程的 運行循環中排隊並儘快執行。

所以基本上它可以發生,該方法被立即調用,就好像我剛剛發送的直接消息,引起-doSomethingInNextRunLoop-doSomeOtherThings之前執行?

我該如何確定它將被稱爲a.s.a.p.但永遠不會在這個相同的運行循環迭代?

澄清措辭:運行循環我的意思是主線程和所有方法必須返回的迭代,直到線程爲新事件再次準備好。

回答

9

如果你擔心蘋果有一天會特殊延遲0,你總是可以指定延遲1e-37左右。雖然performSelector:withObject:afterDelay:的文檔可以很容易讀取,以保證選擇器將始終安排在下一次運行循環迭代中。

如果你擔心蘋果可能會有某天特例延遲少於某個任意下限,那麼你總是可以嘗試使用NSRunLoop的performSelector:target:argument:order:modes:,文檔特別指出它將爲下一次運行循環計劃執行。

+0

棒極了!一個類別來解決這個問題是有道理的。 – openfrog

0

當然,你只是這樣做;

[self doSomeOtherThings]; 
[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0]; 

它保證你想要的執行順序。

+1

這並不總是很方便(或可能的)來重新排列以這種方式中的代碼的情況下比用於說明這個簡單的例子複雜得多。 – Anomie

+0

不是。在NEXT運行循環迭代中有很好的理由執行。其中之一:讓UI刷新。提高感知性能。等等。除此之外,Anomie是對的。 – openfrog

+0

當然,來自Anomie的迴應觸及頭部,我只是指出在某些情況下,代碼重新排列也可以解決問題。有點像寫作者的塊,有時開發人員會掛斷解決問題的一種特殊方式,實際上有一個橫向計劃B. FWIW我沒有意識到任何標準performSelector:withObject:afterDelay:0的實例導致阻止和頻繁使用該技術來優化他人編寫的UI代碼。 – Roger

1

我認爲你閱讀文檔的結論是錯誤的。

所以基本上它可以發生,該方法被立即調用,就好像我剛剛發送的直接消息

號你引用文檔的部分說,選擇總是排隊上運行循環,不管是什麼。所以它絕不會像直接的信息一樣被執行。

「不一定」的第一句話可能有點誤導,但我認爲第二句話應該明確說明你害怕的事情不會發生。

+0

希望你是對的,因爲我敢打賭,很多人都依賴它爲下一次迭代排隊。不過,還有一些不確定性。 – openfrog

6

相當微不足道的使用GCD(大中央調度):

dispatch_async (dispatch_get_main_queue(), ^{ 
    NSLog (@"This stuff runs in the next iteration of the main run loop"); 
}); 
相關問題