Threadsafe UITableView

时间:2008-12-02 00:59:50

标签: cocoa cocoa-touch multithreading

我正在使用UITableView来显示数组中的一些数据。其他线程可以随时更改此数组。 (我相信数组是可变的,还是只是完全替换,并没有什么区别。)对数组本身的访问是线程安全的。

关于tableview,确保线程安全的正确方法是什么?我担心,例如,我可能会在调用cellForRowAtIndexPath之前将数组更改为更短,从而导致NSRangeException。

我应该......

  1. 强制只在主线程上更改数组? (看起来很难看。)
  2. 维护一个阴影数组并通过KVO观察在主线程上更新?
  3. ???必须有一个更好的解决方案......

3 个答案:

答案 0 :(得分:6)

根据您的描述,您确实有两个不同的数据集:

  • 模型中存在的实际数据
  • 显示给用户的数据

因此,实际上,你已经拥有了一个“阴影”数组(虚拟阴影,它可能会将这个比喻拉得太远)。我想说你最好的办法是将这种安排形式化,并保留一个只在主线程中修改的“显示”数组。在其中,您可以拥有来自“真实”数组的对象;因为它们只是指针,所以你不会放弃太多的记忆。

线程是邪恶的。

答案 1 :(得分:3)

在不了解您的应用程序的情况下,我认为更好的解决方案之一是将数组保留在主线程上,并在另一个线程需要进行更改时将其分派回来。像这样:

dispatch_async(dispatch_get_main_queue(), ^{
                [array addObject:object];
                [tableView reloadData];
            });

当然,使用调度API可以使事情变得更复杂,但它确实可以处理锁定和一切。绝对比使用NSLock更优雅。它只适用于iOS 4或更高版本。

答案 2 :(得分:1)

我有同样的情况。我有一组C ++对象,它们在tableview中提供信息。

正如Ben所说,我还有一个临时的“影子”阵列,通过互联网下载新的信息。查询完成后,我将该数组与支持tableview的数组进行协调,这非常快。问题是如何在对帐期间保护阵列。

我正在主线程上进行协调,但我不确定这是否足以防止冲突,尤其是当用户在查询待处理时点击某个条目时;他正在查看细节的基础对象可能会被吹走。

这里有一个与你(和我的)类似的问题: Update UITableView using threads

但是回答是因为他的背景操作花了太长时间而不是回答他的问题。

我将使用NSLock,并在更改数组和所有UITableView委托方法之前获取它,除非有人有更好的想法。