我正在使用UITableView来显示数组中的一些数据。其他线程可以随时更改此数组。 (我相信数组是可变的,还是只是完全替换,并没有什么区别。)对数组本身的访问是线程安全的。
关于tableview,确保线程安全的正确方法是什么?我担心,例如,我可能会在调用cellForRowAtIndexPath之前将数组更改为更短,从而导致NSRangeException。
我应该......
答案 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委托方法之前获取它,除非有人有更好的想法。