跳到主要内容

Object-C如何实现一个线程安全的 NSMutableArray?

参考答案:

在 Objective-C 中,NSMutableArray 并不是线程安全的。如果你需要在多线程环境中使用 NSMutableArray,并且希望它是线程安全的,你可以采取以下几种策略:

  1. 使用锁(Lock): 你可以使用 @synchronized 指令或者 NSLock 对象来确保在修改 NSMutableArray 时只有一个线程可以访问。

    @interface ThreadSafeMutableArray : NSObject
    @property (nonatomic, strong) NSMutableArray *array;
    @property (nonatomic, strong) NSLock *lock;
    
    - (instancetype)init;
    - (void)addObject:(id)anObject;
    - (void)removeObject:(id)anObject;
    // 其他必要的方法
    @end
    
    @implementation ThreadSafeMutableArray
    
    - (instancetype)init {
        self = [super init];
        if (self) {
            _array = [NSMutableArray array];
            _lock = [[NSLock alloc] init];
        }
        return self;
    }
    
    - (void)addObject:(id)anObject {
        @synchronized(self.lock) {
            [self.array addObject:anObject];
        }
    }
    
    - (void)removeObject:(id)anObject {
        @synchronized(self.lock) {
            [self.array removeObject:anObject];
        }
    }
    
    // 实现其他必要的方法
    @end
    
  2. 使用 GCD(Grand Central Dispatch): 使用 GCD 的队列(dispatch queue)来同步对 NSMutableArray 的访问。

    dispatch_queue_t queue = dispatch_queue_create("com.yourcompany.yourapp.threadsafearray", DISPATCH_QUEUE_SERIAL);
    
    NSMutableArray *array = [NSMutableArray array];
    
    dispatch_async(queue, ^{
        [array addObject:@"Object"];
    });
    
    dispatch_async(queue, ^{
        [array removeObject:@"Object"];
    });
    

    在这种情况下,你不需要自己管理锁,因为 GCD 会为你管理队列的串行执行。

  3. 使用线程安全的容器类: iOS 5.0 引入了 NSBlockOperationNSOperationQueue,它们可以确保操作的原子性。虽然这不是直接针对 NSMutableArray 的解决方案,但它可以帮助你以线程安全的方式执行一系列操作。

    另一个选择是使用 NSMutableArray 的子类,例如 MTMutableArray,它提供了一个线程安全的实现。这是从 Mac OS X 10.6 和 iOS 4.0 开始提供的 libdispatch 库中的一部分。

  4. 使用线程安全的第三方库: 有些第三方库提供了线程安全的 NSMutableArray 实现,如 ReactiveCocoa 的 RACMutableArray

请记住,使用锁或其他同步机制可能会影响性能,因为线程间的竞争可能导致线程阻塞。在设计多线程应用程序时,需要权衡线程安全和性能之间的关系。

最后,如果你正在使用 Swift,你可能会考虑使用 Swift 的原生集合类型,如 Array,它们在某些情况下是线程安全的,或者使用 Swift 的并发原语,如 DispatchQueueactor 隔离。