为什么说NSMutableArray是线程不安全的?

原理

NSMutableArray是线性表中的顺序存储结构,是一块连续的内存,当添加新的元素时,容量已经等于当前的大小的时候(存不下了),会依次执行下面3步:

  • 重新开辟一块大小为当前容量两倍的数组
  • 把原数据拷贝过去
  • 释放掉旧的数组

完事后再把这个元素加在后面。

防范措施(使用信号量)

代码如下:

@interface ViewController ()
@property (nonatomic, strong) NSMutableArray *mArray;
@property (nonatomic, strong) dispatch_semaphore_t semaphore;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
     self.semaphore = dispatch_semaphore_create(1);
    
    dispatch_queue_t queue = dispatch_queue_create("test_queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        [self test];
    });
    
    dispatch_async(queue, ^{
        [self test];
    });
}

- (void)test {
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    for (int i = 0; i < 10; i++) {
        [self.mArray addObject:@(i)];
    }
    for (int i = 0; i < self.mArray.count; i++) {
        NSNumber *number = self.mArray[i];
        NSLog(@"currentThread: %@----%@", [NSThread currentThread],number.stringValue);
    }
    dispatch_semaphore_signal(self.semaphore);
}

- (NSMutableArray *)mArray {
    if (!_mArray) {
        @synchronized(self) {
            if (!_mArray) {
               _mArray = @[].mutableCopy;
            }
        }
    }
    return _mArray;
}

@end

你可能感兴趣的