NSMutableArray集合和@Synchronized块

在Objective C中,我使用来自各种线程的NSMutableArray实例,并使用@synchronized使其线程安全。 目前我对这个数组的所有访问都被一个@synchronized块,甚至objectAtIndex:方法保护着。 不过,我想知道哪些方法真的需要用@synchronized来保护。 我需要保护读取权限吗?

如果'ObjectAtIndex'没有被保护,并且与'removeObject'同时被调用,会发生什么?

如果所有的方法都受@synchronized保护,性能怎么样? (我写一个tcp / udp游戏服务器,真的不想过度保护这些数组,如果它会减less性能或产生锁)。

例如,我想'containsObject:'方法将枚举find该对象,我应该避免在另一个线程中的'removeObject:'contifnt调用。

也许一个好的解决办法是有太多不同的锁(读写访问)…

帮助和build议,欢迎!

非常感谢。

请在下面find示例代码来说明:

@interface TestClass : NSObject { NSMutableArray * array; } @end @implementation TestClass - (id)init { self = [super init]; if (self) { array = [NSMutableArray array]; } return self; } -(id)objectAtIndex:(NSUInteger)index { @synchronized(array) **// IS IT USEFUL OR NOT ??** { return [array objectAtIndex:index]; } } -(void)removeObject:(id)object { @synchronized(array) { [array removeObject:object]; } } -(void)compute { @synchronized(array) { for (id object in array) { [object compute]; } } } @end 

是的,你必须同步读取访问,以防止它们与突变同时发生。 但是,读取访问可以安全地与其他读取访问同时运行。

如果你有多个阅读器,那么值得研究一个读写lockingscheme。 你可以使用pthread读写锁(即pthread_rwlock_...() )。

或者,您可以在OS X 10.7+和iOS 5+上使用带有“障碍”例程的GCD。 创build一个专用的并发队列。 以正常的方式提交所有的读取操作(例如dispatch_sync() )。 使用屏障例程(如dispatch_barrier_async()向其提交变异操作。 (它可以是asynchronous的,因为在继续之前您通常不需要知道变异已经完成,您只需要知道在提交变异后提交的所有阅读将会看到变异的结果,并且障碍保证了这一点。 )

如果您有权访问“第210场会议 – 掌握Grand Central Dispatch”的WWDC 2011会议video,则可以了解更多信息。

你需要意识到你所做的事实际上并没有太大的帮助。 例如,如果你的数组有10个元素,而你调用[myObject objectAtIndex:9],而另一个线程调用[myObject removeObject:someObject],那么机会是第一次调用访问一个不存在的数组元素,并抛出一个exception。

如果其他线程可以删除或插入对象,objectAtIndex实际上并不有用。