对 Objective-C 容器的读/写访问通常不是线程安全的。
您可以通过将容器关联到专用调度队列,然后在该队列上执行所有读取和写入访问来解决并发问题。队列可以是串行的或并发的。
您可以在任何专用线程上调用以下方法。但是,我建议最终将您的实现切换为调度 lib。
在这里,我们创建一个串行队列:
dispatch_queue_t sync_queue = dispatch_queue_create("sync_queue", NULL);
可以异步进行写访问:
- (void) addItem:(id)item forKey:(NSString*)key {
dispatch_async(sync_queue, ^{
[self.dict setObject:item forKey:key];
});
}
返回值的读访问必须是同步的:
- (id) itemForKey:(NSString*)key {
__block id item;
dispatch_sync(sync_queue, ^{
item = [self.dict objectForKey:key];
});
return item;
}
您可以为任何任务定义类似的包装器:
- (void) iterate {
dispatch_async(sync_queue, ^{
for (id item in self.dict) {
...
}
});
}
使用并发队列:
dispatch_queue_t sync_queue = dispatch_queue_create("sync_queue", DISPATCH_QUEUE_CONCURRENT);
写访问可以异步进行,需要一个屏障:
- (void) addItem:(id)item forKey:(NSString*)key {
dispatch_barrier_async(sync_queue, ^{
[self.dict setObject:item forKey:key];
});
}
返回值的读取访问必须是同步的,并且不需要屏障。
基本上,同步队列和并发队列没有区别:
- (id) itemForKey:(NSString*)key {
__block id item;
dispatch_sync(sync_queue, ^{
item = [self.dict objectForKey:key];
});
return item;
}