6

我有一个使用可变数组的类,该数组在大量读取(新项目到达)后修改一次。

问题是,当需要对数组进行变异时,读取会不断出现。

目前为了避免这个问题,它每次读取它在副本上执行的操作:

[[theArray copy] operation] //operation being indexOfObject:, objectAtIndex: objectsAtIndexes:, etc.

副本变得非常昂贵,尤其是在不需要的时候(所有那些数组没有发生突变的时候)。

如何锁定数组以延迟对其进行突变时的访问?

4

3 回答 3

10

将您所有的数组访问放到一个串行调度队列中。这将防止任何两个操作同时发生。请参阅并发编程指南中的“消除基于锁的代码”

如果您可以要求 iOS >= 4.3,您可以使用并发自定义队列和调度屏障进行突变操作。这将允许读取同时发生,但是当需要写入时,它们将被暂停直到写入完成。作为屏障提交的块本质上是在并发队列上串行执行的——它不会在所有先前的块完成之前开始,任何后续块也不会在屏障块完成之前开始。(这是 Justin 提到的读写锁的 GCD 版本。)我将您引向无与伦比的 Mike Ash 以获取此.

于 2012-08-09T19:29:38.117 回答
5

最简单的方法是使用@synchronized,如下所示:

-(void) accessTheArray {
    MyClass *obj;
    @synchronized(theArray) {
        obj = [theArray objectAtIndex:...];
    }
    [obj someMessage];
}

编辑:如果不使用 ARC,您可能希望保留/自动释放该对象,否则它可能会在someMessage调用之前从数组中删除(并释放)(感谢omz的出色评论)。

于 2012-08-09T19:25:44.193 回答
2

在这种情况下,您会考虑使用读/写锁。Cocoa 不提供它们,但pthread_rwlock_t在 pthreads 接口中可用——在pthread.h. @synchronized请注意,这将比,甚至是普通锁更有效(对于您的使用) 。

于 2012-08-09T19:25:28.680 回答