2010-10-11 27 views
1

將經常從後臺線程更新的數據源與GUI主線程同步的最佳方法是什麼?從後臺線程更新NSTableView數據源

我應該在每個方法調用周圍放置一個pthread互斥量嗎? 這似乎是相當沉重的我。

編輯:我在尋找一個解決10.5

回答

2

你可以隨時更新在主線程模型和表視圖。 NSObject中有像performSelectorOnMainThread:withObject:waitUntilDone:這樣的函數,它允許您輕鬆地在主線程上執行函數調用。所以,你可以更新你的模型:

[model performSelectorOnMainThread:@selector(addObject:) withObject:newObject waitUntilDone:YES]; 

,然後用此更新您的實現代碼如下:

[tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 

事情得到,如果你需要傳遞多個對象更加複雜,因爲你需要使用調用,但我發現這些功能可以在大多數情況下使用。

+0

嗯,但我的主要想法是從主線程獲取工作負載。該模型可以有幾萬個列表項。當主線程阻塞10ms時,你可以感受到它。 – Lothar 2010-10-11 14:21:26

+0

假設在數組中創建對象將花費大量時間,而不是將它們插入到數組中。如果您擔心主線程單獨添加對象的負載,則可以使用addObjectsFromArray:一次批量添加多個對象。否則,如果沒有使用GCD(如果你正在創建一個10.5應用程序,那麼你不能使用它),那麼你必須使用NSLock。 – 2010-10-11 18:37:08

1

這是Snow Leopard還是您希望保留與10.2+兼容?如果您在保持向後兼容性方面死心塌地,則可以將應用更新的代碼分解爲另一種方法,並使用performSelectorOnMainThread:withObject:waitUntilDone:

來調用它。或者,如果您希望使用新玩具並保留代碼更具可讀性(即將方法數量保持在最低限度),您可以在線提供blocksGrand Central Dispatch。像下面的內容就足夠:

// The following line is (presumably) executed in your background thread 
NSMutableArray *newEntries = [self doSomeHeavyLiftingInBackground]; 
dispatch_async(dispatch_get_main_queue(), ^{ 
    /* The following lines are executed in the context of your main 
    thread's run loop. You don't need to mess about with locks as it 
    will not be executed concurrently with UI updates. */ 
    id<NSTableViewDataSource> dataSource = [self getDataSource]; 
    NSMutableArray *dataSourceInnards = [dataSource whyIsThisMethodHere]; 
    [dataSourceInnards addObjectsFromArray:newEntries]; 
    [dataSource tellTableViewToReload]; 
}); 

這有不必扭曲你的代碼向通一單對象 - 一個-獨立法模式的優勢。

+0

幾秒鐘之內捱打,但希望這突出了幾個選擇。 :) – 2010-10-11 13:04:58