Read/Write access to Objective-C containers is generally not thread safe.
You can solve the concurrency problem through associating the container to a dedicated dispatch queue, and then executing ALL read and write accesses on that queue. The queue can be either serial or concurrent.
You can invoke the following methods on any dedicated thread. However, I would suggest to switch your implementation to dispatch lib eventually.
Here, we create a serial queue:
dispatch_queue_t sync_queue = dispatch_queue_create("sync_queue", NULL);
Write access can be made asynchronously:
- (void) addItem:(id)item forKey:(NSString*)key {
dispatch_async(sync_queue, ^{
[self.dict setObject:item forKey:key];
});
}
Read access which returns a value must be synchronous:
- (id) itemForKey:(NSString*)key {
__block id item;
dispatch_sync(sync_queue, ^{
item = [self.dict objectForKey:key];
});
return item;
}
You can define similar wrappers for any task:
- (void) iterate {
dispatch_async(sync_queue, ^{
for (id item in self.dict) {
...
}
});
}
Using a concurrent queue:
dispatch_queue_t sync_queue = dispatch_queue_create("sync_queue", DISPATCH_QUEUE_CONCURRENT);
Write access can be made asynchronously and needs a barrier:
- (void) addItem:(id)item forKey:(NSString*)key {
dispatch_barrier_async(sync_queue, ^{
[self.dict setObject:item forKey:key];
});
}
Read access which returns a value must be synchronous, and it doesn't need a barrier.
Basically, there's no difference for synchronous and concurrent queues:
- (id) itemForKey:(NSString*)key {
__block id item;
dispatch_sync(sync_queue, ^{
item = [self.dict objectForKey:key];
});
return item;
}