异步更新NSTableView数据源

时间:2014-07-24 16:03:22

标签: objective-c multithreading cocoa nstableview appkit

我一直在谷歌上搜索这个问题,但似乎无法就这类问题的解决方案达成共识。当我使用带有NSTableView的数据源时,如果我需要在后台填充数据源,那么我会想到一些关于线程的问题。我希望能在这里得到一些指导。

  1. 如果我在主线程调用[NSTableView numberOfRowsInTableView:]和[NStableView tableView:objectValueForTableColumn:row:]之间修改了数据源,会发生什么?如果表格视图要求的对象不再有效,我该怎么办?

  2. 是否仅在主线程上对数据源进行了更改?解决了这种情况?

  3. 如果答案是2,它是否适用于使用绑定的情况?

2 个答案:

答案 0 :(得分:1)

如果您的数据源需要一些时间来填充,并且您当前正在显示包含旧数据的表格,我认为您有几个选项:

  • 在重新填充时显示UI上的微调器,然后调用[tableView reloadData]
  • 保留旧数据以使tableView保持响应,然后在获取/计算新数据后,告诉数据源有关新NSArray(或任何保存新数据的对象),并调用[tableView reloadData]。 / LI>

您无法动态更改支持数据源的数据,除非您随时通知tableView每个项目/行的更改。

要解决线程部分,可以使用后台线程填充新数据的NSArray,一旦完全切换到主线程,并在该调用上[dataSource setBackingArray:newStuff]; [tableView reloadData];

答案 1 :(得分:1)

非常感谢Graham Perks对其中一个答案的评论。这实际上是一个值得明确写出的答案。我只想从我的项目中添加小片段作为插图:

- (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];
}