2013-11-05 25 views
1

我註冊了NSTask對象的NSTaskDidTerminate通知。一切工作正常,但任務需要時間啓動,所以我已經將啓動移動到背景(與performSelectorInBackground)。NSTask不發送終止通知

  • 與通知中心和任務本身的創建登記發生在主線程
  • 在幾秒鐘內得到任務在後臺啓動後
  • 通知不再到達:(

有沒有辦法以某種方式調整通知的代碼以再次使用?

+0

爲了以防萬一,你可以發佈初始化代碼,註冊代碼和執行異步代碼async –

+0

@lead_the_zeppelin一切都很標準,異步代碼只是[task launch]命令。我也嘗試過移動通知註冊,但沒有奏效。無論如何,現在並不重要,因爲我現在在啓動後執行waitUntilExit,之後我手動調用通知中心應該調用的方法。它再次運作,所以我猜這個問題解決了。 – Marius

回答

1

NSTask註冊一個專用運行循環源來監視啓動它的線程的運行循環中的任務。如果該線程不能繼續存在並運行其運行循環,那麼Cocoa不會注意到該任務已終止。如果Cocoa沒有注意到它,那麼它不能將通知發佈給你的觀察者。

如果你正在用-performSelectorInBackground:...做的唯一事情是調用任務的-launch方法,那麼該線程不會停留或運行其運行循環。 (同樣,不能依賴服務GCD隊列的工作線程來保持現有的或運行其運行循環。)您可以在後臺調用更復雜的方法來啓動任務,然後運行運行循環,但那應該沒有必要。

您確定啓動任務需要花費任何可觀的時間嗎?它確實不應該。 NSTask的設計使得可以在主線程上創建,啓動和監視任務,而不會使其無響應。

+0

它確實需要時間,因爲任務是一個「ssh」隧道連接,並且其中有很多。我已經通過等待任務手動完成(在後臺)解決了這個問題,並且他們將通知「發佈」給我自己的主線程。無論如何,感謝您的解釋,我認爲這是非常豐富的,所以我會將其標記爲答案。 – Marius

+0

該任務可能需要一段時間才能運行,但啓動*應該不需要太多時間。 \ *聳肩\ * –

+0

嗯,它的確如此。 1-3秒。而且,由於這些連接有一些 - 其影響非常明顯:) – Marius

1

首先關閉NSTask is not thread safe。您需要小心當從單獨的線程使用它的一個實例或完全避免它。

其次據我所知NSNotifications只在通知發佈的線程上傳遞。該通知由NSTask對象本身發佈,該對象本身顯然終止於輔助線程,但您已在主線程上註冊通知。有關更多信息,請參閱the docs

你能簡單地處理後臺線程上的整個任務和通知序列嗎?

+0

嘗試在後臺線程上做,但通知沒有到達。無論如何,我不想浪費更多時間,所以我只是簡單地在bg線程中發出waitUntilExit,併爲我做了同樣的事情,所以現在問題得到解決。 – Marius