NSMutableArray集合和@Synchronized块

时间:2013-06-13 15:44:22

标签: ios objective-c multithreading nsmutablearray synchronized

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

如果'ObjectAtIndex'在'removeObject'的同时没有受到保护和调用,会发生什么?

如果所有方法都受@synchronized保护,性能如何? (我正在编写一个tcp / udp游戏服务器,如果它会降低性能或生成锁定,我真的不想过度保护这些数组)。

例如我假设'containsObject:'方法将枚举以查找对象,并且我应该避免在另一个线程中对'removeObject:'进行concurent调用。

也许一个好的解决方案是拥有太多不同的锁(用于读写访问)......

欢迎提供帮助和建议!

非常感谢。

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

@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

2 个答案:

答案 0 :(得分:5)

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

如果您有多个读者,那么值得研究读写锁定方案。您可以使用pthread读写锁(即pthread_rwlock_...())。

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

如果您有权访问WWDC 2011 session video for Session 210 - Mastering Grand Central Dispatch,则可以了解详情。

答案 1 :(得分:0)

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

如果其他线程可以删除或插入对象,则

objectAtIndex不是很有用。