现在的位置: 首页 > 综合 > 正文

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

2019年11月13日 综合 ⁄ 共 1154字 ⁄ 字号 评论关闭

  NSMutableArray是线程不安全的,当有多个线程同时对数组进行操作的时候可能导致崩溃或数据错误

  线程锁:使用线程锁对数组读写时进行加锁

  派发队列:在《Effective Objective-C 2.0..》书中第41条:多用派发队列,少用同步锁中指出:使用“串行同步队列”(serial synchronization queue),将读取操作及写入操作都安排在同一个队列里,即可保证数据同步。

  而通过并发队列,结合GCD的栅栏块(barrier)来不仅实现数据同步线程安全,还比串行同步队列方式更高效。

  简单来说就是操作前 lock 操作执行完 unlock。

  但注意,每个读写的地方都要保证用同一个 NSLock进行操作。

  NSLock *arrayLock = [[NSLock alloc] init];

  [...]

  [arrayLock lock]; // NSMutableArray isn't thread-safe

  [myMutableArray addObject:@"something"];

  [myMutableArray removeObjectAtIndex:5];

  [arrayLock unlock];

  另一种方式是利用 GCD 的 concurrent queue 来实现,个人感觉更高效。

  dispatch_queue_t concurrent_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

  For read:

  (id)objectAtIndex:(NSUInteger)index {

  __block id obj;

  dispatch_sync(self.concurrent_queue, ^{

  obj = [self.searchResult objectAtIndex:index];

  });

  return obj;

  }

  For insert:

  (void)insertObject:(id)obj atIndex:(NSUInteger)index {

  dispatch_barrier_async(self.concurrent_queue, ^{

  [self.searchResult insertObject:obj atIndex:index];

  });

  }

  For remove:

  (void)removeObjectAtIndex:(NSUInteger)index {

  dispatch_barrier_async(self.concurrent_queue, ^{

  [self.searchResult removeObjectAtIndex:index];

  });

  }

抱歉!评论已关闭.