2014-07-24 48 views
1

我一直在Google上搜索這個主題,但似乎沒有找到解決這類問題的共識。當我使用帶有NSTableView的數據源時,如果我需要在後臺填充數據源,那麼在我的腦海中會出現一些關於線程的問題。我希望能在這裏得到一些指導。和:如果我修改了主線程調用[NSTableView的numberOfRowsInTableView]之間的數據源異步更新NSTableView數據源

  1. 會發生什麼[NSTableView的的tableView:objectValueForTableColumn:行:]?如果表視圖所要求的對象不再有效,我該怎麼辦?

  2. 僅在主線程上對數據源進行更改才能解決此情況?

  3. 如果2是答案,它是否適用於使用綁定的情況?

回答

1

如果數據源需要一些時間來填充,而你當前顯示與舊數據的表,我認爲你有兩個選擇:

  • 顯示一個微調在UI當重新人口發生時,然後調用[tableView reloadData]
  • 保留舊數據,以便tableView保持響應,然後一旦新數據被提取/計算,告訴數據源關於新的NSArray(或任何對象持有新數據),並調用[tableView reloadData]。

您不能隨時更改支持數據源的數據,除非您通知每個項目/行的tableView隨時更改。

要解決線程部分,可以使用後臺線程填充新數據的NSArray,一旦完成切換到主線程,並在該調用時[dataSource setBackingArray:newStuff]; [tableView reloadData];

+0

格雷厄姆,從概念上說我明白你在說什麼。但在我看來,我修改數據源和調用[tableView reloadData]是關鍵。例如:1)主線程調用[NSTableView numberOfRowsInTableView:],2)我清理另一個線程的數據源,3)主線程調用[NStableView tableView:objectValueForTableColumn:row:],索引不再有效。 4)調用[tableView reloadData]。 – mr49

+1

對,所以要避免這個問題。你的數據源可能有兩個數組,currentData和incomingData。響應表格視圖時始終使用currentData。一旦incomingData完成,將其分配給currentData並告訴表重新加載。分配和重新加載的調用之間沒有「中間」,因此表視圖保持一致。 –

1

非常感謝格雷厄姆·帕克斯在評論其中一個答案。這實際上是一個值得明確寫出來的答案。我想只是從我的項目中添加小片段作爲插圖:

- (void) populateTable 
{ 
    DAL *dal = [[DAL alloc] init]; // MySQL engine 
    NSMutableArray *tmp = [NSMutableArray new]; 
    NSMutableArray *records = [dal RetrieveRecordswithSql:@"select id, serial, scannerid, scans, offloaded, uploaded from scan_set_v3" withColumnsCount:@(6) andColumnsDelimiter:ScanSetRecordColumnDelimiter]; 
    for (NSString *rec in records) { 
     ScanSetRecord *newRec = [[ScanSetRecord alloc] initWithScanSet:rec]; 
     if (newRec) { 
      [tmp addObject:newRec]; 
     } 
    } 
    self.dataArray = tmp; 
    [self.tableView reloadData]; 
}