Objective-C __block关键字和线程安全

fir*_*der 3 cocoa cocoa-touch objective-c cocoa-design-patterns objective-c-blocks

我想知道如何__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];
}
Run Code Online (Sandbox Code Playgroud)

这里将操作添加到并发队列中,并且dictionary可能同时从不同的线程访问var.

这样安全吗?如果没有,我如何访问dictionary安全?

Pet*_*sey 5

正如UIAdam在评论中所说,在__block这里没有为你做任何事情; 你正在改变字典,而不是分配给变量.变量将继续永远指向同一个字典.

事实上,这__block可能实际上对你有害,因为这意味着该块不会捕获变量.如果您不使用ARC,这意味着不会保留字典,并且该块可能很快就会向死对象发送消息.我不确定ARC是否改变了这一点.无论如何,你应该放弃__block这个变量; 如果没有别的,代码更清楚地表达你的意图,没有它.

至于你的实际问题,关于线程安全,这段代码并不安全.根据Thread-Safety Summary,可变集合类不是线程安全的:您必须一次只从一个线程向可变集合发送消息.同步将是一种方式; 将队列的最大并发操作数设置为1将是另一个.

  • 在ARC模式下,保留`dictionary` _will_.以下是有关此内容的更多信息:http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html(请参阅"块"部分) (3认同)