2011-05-26 40 views
2

我有一個窗口,顯示一些數據在NSTableView。這些數據在後臺加載。數據加載線程在windowDidLoad:方法中啓動。如果窗口在加載完成前關閉,後臺線程應該被取消。我通過發信號通知windowWillClose:委託方法中的線程並等待後臺線程完成。可取消加載後臺線程

現在,這一切都完美的作品。但我有一個問題:如何更新表視圖中的數據?我嘗試通過performSelectorOnMainThread:嘗試呼叫reloadData,但這會導致競爭條件:reloadData調用有時在窗口關閉命令之後在主線程上排隊,並且在窗口關閉後執行,並且所有事情都以火焰進行。

什麼是控制和溝通後臺線程的最佳方式?

回答

3

嗯,你知道,這正是使用線程複雜的原因:你總是面臨同步問題。

我的建議是,而不是從你的線程中調用[tableView reloadData],只是信號控制器(通過調用的方法controllerShouldReloadTable),讓你的控制器做檢查,如果windowWillClose被稱爲與否。有可能你的控制器在controllerShouldReloadTable的時候也被釋放了,爲了解決這個問題,你肯定需要從輔助線程中獲得retain控制器。

在旁註中,我將取消viewDidUnload(對稱)中的線程。

最重要的是:我會使用異步調用和一個委託類,以便整個多線程問題可以在其根部解決。

編輯:異步發送請求不會阻止發送線程等待響應。相反,異步發送(對於NSURLConnection被稱爲start)立即返回(所以沒有阻塞),並且當接收到響應時,將調用委託方法(即,connectionDidFinishLoading:),以便可以更新模型和UI。看看NSURLConnection文檔,但像往常一樣,我強烈建議使用[ASIHTTPRequest][2],其中有many advantages

+0

這是一個好主意,我會試試這個。但是我不能使用'viewDidUnload',因爲它只能在iOS上使用,而在Cocoa中,窗口不是視圖。我不認爲我需要保留控制器,因爲'performSelector'方法仍然保留目標。你能詳細說明你的意思是「異步調用和委託類」嗎?我不確定我是否明白這一點。 – 2011-05-26 20:06:00

+0

我嘗試過了,現在看起來可行。如果線程編程只是不那麼難... – 2011-05-26 20:51:33

+0

Jakob,看我的編輯..你會喜歡異步I/O,它是如此自然的事件循環系統... – sergio 2011-05-26 21:42:36