2012-09-10 39 views
1

我設置到不同的隊列中運行,並調用延遲後的另一種方法塊:performSelector:withObject:afterDelay:不排隊選擇

piemanQ = dispatch_queue_create(PIEMAN_QUEUE_NAME, NULL); 
dispatch_async(piemanQ, ^{ 
    [self performSelector:@selector(sendReadyToPieman) withObject:nil afterDelay:1.0]; 
}); 

我希望第二個以後的@selector(sendReadyToPieman)火災,但是什麼都沒發生。我已經通過performSelector:withObject:afterDelay:上的doco讀過,它講述了通過當前隊列上的定時器添加的方法。我已經檢查了當前的隊列運行循環模式,但它返回nil。

我確定我以前做過這樣的代碼,但我已經在兩個不同的地方嘗試過這種情況,並且在兩種情況下它都沒有運行。但如果我用dispatch_after(...)替換它一切正常。

任何人都可以點亮一下嗎?

回答

2

你應該換一個NSOperationQueue代替操作:

NSOperationQueue *piemanQ = [[NSOperationQueue alloc] init]; 
piemanQ.name = @"some name"; 
[piemanQ addOperationWithBlock:^{ 
    [self performSelector:@selector(sendReadyToPieman) withObject:nil afterDelay:1.0]; 
}]; 

這是自動同步。最好使用Objective-C解決方案來解決問題的C解決方案。

+0

一個很棒的建議。我還沒有使用過NSOperation隊列,但是我懷疑交換給他們會將我有的其他代碼串起來。我必須試一試,看看會發生什麼。 – drekka

+0

你的代碼看起來會比所有這些C方法好得多:) –

+0

我同意你在這裏所說的一切。但是,唉,它並沒有回答原來的問題。這個「NSOperationQueue」的演繹會遇到與原始問題中的代碼完全相同的問題。 – Rob

2

我的猜測是:dispatch_async做它說的,它使以下東西運行異步。你排隊你的選擇器,然後塊完成,整個異步的東西消失。當然包括排隊的選擇器。

對於performSelector執行任何操作,線程必須處於活動狀態,並且需要執行runloop。

+0

這是有道理的,但我的讀書說performSelector添加一個NSTimer的隊列,延遲後觸發執行選擇器。我讀過的GCD信息說,隊列不會關閉,直到隊列中的所有內容都執行完畢。因此理論上通過執行performSelector:withObject:afterDelay:應該在隊列中排隊另一個NSTimer,並因此停止它關閉自己。至少這是我從doco中瞭解到的。但它似乎並不奏效。用明確的dispatch_Async代替它確實有效。 – drekka