I'm wondering how I can make access to a __block
qualified var thread-safe within the context of a method.
Example:
__block NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
for (int i=0; i<20; i++) {
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[dictionary setObject:@"test" forKey:@"test"];
}];
[someConcurrentQueue addOperation:operation];
}
Here the operation is added to a concurrent queue and the dictionary
var will potentially be
accessed from different threads at the same time.
Is this safe? If not, how do I make access to dictionary
safe?
As UIAdam said in his comment, __block
isn't doing anything for you here; you're mutating the dictionary, not assigning to the variable. The variable will continue to point to the same dictionary forever.
In fact, __block
may actually hurt you here, since it means the variable will not be captured by the block. If you're not using ARC, this means the dictionary will not be retained, and the block may be sending messages to a dead object soon. I'm not sure offhand whether ARC changes this. At any rate, you should leave __block
off of this variable; if nothing else, the code more clearly expresses your intent without it.
As for your actual question, about thread-safety, this code is not safe. According to the Thread-Safety Summary, the mutable collection classes are not thread-safe: you must send messages to a mutable collection from no more than one thread at a time. Synchronization would be one way; setting the queue's max concurrent operation count to 1 would be another.