ios - NSMutableArray 集合和@Synchronized block

标签 ios objective-c multithreading nsmutablearray synchronized

在 Objective C 中,我使用来自不同线程的 NSMutableArray 实例,我使用 @synchronized 使其线程安全。目前我对这个数组的所有访问都受到 @synchronized block 的保护,甚至是 objectAtIndex: 方法。尽管如此,我想知道哪些方法调用真的需要用@synchronized 来保护。我需要保护读取权限吗?

如果 'ObjectAtIndex' 不 protected 并在 'removeObject' 的同时被调用,会发生什么情况?

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

例如,我假设“containsObject:”方法将枚举以查找对象,我应该避免在另一个线程中同时调用“removeObject:”。

也许一个好的解决方案是使用不同的锁(用于读取和写入访问)...

欢迎提供帮助和建议!

非常感谢。

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

@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

最佳答案

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

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

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

如果您有权访问 WWDC 2011 session video for Session 210 - Mastering Grand Central Dispatch,您可以了解更多相关信息.

关于ios - NSMutableArray 集合和@Synchronized block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17091389/

相关文章:

ios - 如何在 iOS 应用程序中撤销/取消/注销 "Location Services"

ios - 如何根据从先前 View Controller 中的另一个 FRC 检索的对象来获取 fetchedResultsController 来提供我的 TableView?

c# - 为什么抛出异常时应用程序不会崩溃

objective-c - 将 UIImageView 随机放置在 UIView 上并且不重叠

objective-c - 在 iOS 中获取自动日期

ios - 文档自定义框架 XCode

ios - 如何选择接收到触摸事件的 UIView

ios - 在使用 Objective - C 制作的 App 中使用 Swift 代码

java - Android 异步任务中的 Thread.Sleep()

java - 线程排队时共享列表未更新