我想知道如何在方法的上下文中访问__block
限定的var线程安全。
示例:
__block NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
for (int i=0; i<20; i++) {
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[dictionary setObject:@"test" forKey:@"test"];
}];
[someConcurrentQueue addOperation:operation];
}
此处将操作添加到并发队列中,dictionary
var可能是
同时从不同的线程访问。
这样安全吗?如果没有,我该如何访问dictionary
安全?
答案 0 :(得分:5)
正如UIAdam在评论中所说,__block
在这里没有为你做任何事情;你正在改变字典,而不是分配给变量。该变量将继续永远指向同一个字典。
事实上,__block
实际上可能会对您造成伤害,因为这意味着该块不会捕获该变量。如果您不使用ARC,这意味着不会保留字典,并且该块可能很快就会向死对象发送消息。我不确定ARC是否改变了这一点。无论如何,你应该让__block
离开这个变量;如果不出意外,代码会在没有它的情况下更明确地表达您的意图。
关于你的实际问题,关于线程安全,这段代码不安全。 According to the Thread-Safety Summary,可变集合类不是线程安全的:您必须一次只从一个线程向可变集合发送消息。同步将是一种方式; setting the queue's max concurrent operation count到1将是另一个。
答案 1 :(得分:4)
这是不线程安全但与__block
关键字无关,因为您只是阅读但不写入。
使线程安全的最简单方法是使用@synchronized
关键字
__block NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
for (int i=0; i<20; i++) {
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
@synchronized(dictionary) {
[dictionary setObject:@"test" forKey:@"test"];
}
}];
[someConcurrentQueue addOperation:operation];
}
或者您可以使用NSLock或任何类型的锁定
应阅读此内容以获取更多信息 https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html