我应该使用' volatile'和' __ block'在另一个线程上执行块时的限定符?

时间:2014-10-28 07:54:50

标签: ios objective-c multithreading objective-c-blocks volatile

让我们看一下这段代码:

- (void)addOperationAndWait:(void (^)())operation {
  __block NSException *exception = nil;
  [self.queue addOperationWithBlock:^{
    @try {
      operation();
    }
    @catch (NSException *ex) {
      exception = ex;
    }
  }];
  [self.queue waitUntilAllOperationsAreFinished];
  if (exception) {
    @throw exception;
  }
}

这些代码行在一个线程上执行:

 __block NSException *exception = nil;

  if (exception) {
    @throw exception;
  }

并且这行代码在另一个线程上执行:

exception = ex;

那么我应该将exception变量声明为volatile以确保变量的值不会被使用它的线程缓存吗?

我怀疑是因为这篇文档:

易失性变量对单个变量应用另一种类型的内存约束。编译器通常通过将变量的值加载到寄存器中来优化代码。对于局部变量,这通常不是问题。但是,如果该变量在另一个线程中可见,则此类优化可能会阻止另一个线程注意到对它的任何更改。将volatile关键字应用于变量会强制编译器在每次使用时从内存加载该变量。如果变量的值可以随时由编译器可能无法检测到的外部源更改,则可以将变量声明为volatile

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html

2 个答案:

答案 0 :(得分:1)

volatile对于所有的变量的多线程访问没有帮助。使用原子操作,或使用原子属性。

答案 1 :(得分:0)

当变量可以被编译器看不到的东西改变时,使用

volatile。在这里,编译器可以看到发生的一切。