从后台线程更新NSTableView数据源

时间:2010-10-11 12:48:54

标签: multithreading cocoa nstableview

将经常更新的后台线程数据源与GUI主线程同步的最佳方法是什么?

我应该在每个方法调用周围放置一个pthread互斥锁吗? 这似乎也很重要。

编辑:我正在寻找10.5解决方案

2 个答案:

答案 0 :(得分:2)

您可以随时更新主线程上的模型和表视图。像performSelectorOnMainThread:withObject:waitUntilDone:这样的NSObject中有一些函数可以让你轻松地在主线程上执行函数调用。因此,您可以使用以下命令更新模型:

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

然后,用这个更新你的tableview:

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

如果你需要传递多个对象,事情变得更复杂,因为那时你需要使用调用,但我发现这些函数大部分时间都可以使用。

答案 1 :(得分:1)

这是雪豹还是你希望保持与10.2+的兼容性?如果您在保持向后兼容性方面处于死胡同状态,则可以将应用更新的代码分解为另一种方法并使用performSelectorOnMainThread:withObject:waitUntilDone:

进行调用

或者,如果您更喜欢玩新玩具并保持代码更具可读性(即将方法数量保持在最低水平),您可以通过blocks和{{{}进行在线提供。 3}}。如下所示就足够了:

// 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];
});

这样做的好处是不必将代码扭曲到单个对象到单独的方法模式。