2011-03-17 48 views
6

我想将Java代码转换为Objective C代码。而java代码包含定义为volatile的变量。我看了网上和“挥发”在使用Java作为follwingObjective C,将Java中的volatile变为Objective C的最佳方法是什么?

Essentially, volatile is used to indicate that a variable's value will be modified by different threads. 

所以,如果我要设置变量为挥发性的目标C,因为变量是要由不同的线程访问,然后我不需要将这些变量设置为volatile,因为我可以将这些变量设置为原子?

+0

我实际上并不知道Objective-C中的等价物,但我可以告诉你,Java中的“volatile”不是关于原子性的:它是关于缓存的。一个volatile成员变量不会被缓存在一个寄存器中,而是每次需要时从内存中获取。 – 2011-03-17 04:03:41

+2

在Objective-C中需要'volatile'的情况非常罕见(几乎只用于硬件寻址)。如果你认为你需要变化,那么你总是会犯错。 – bbum 2011-03-17 06:18:50

回答

18

volatile关键字也存在于Objective-C中。你可以使用它。

这是因为Objective-C的是C.

的一个超集

声明属性为atomic不会纠正一下volatile是为了做。 volatile有效地告诉编译器不要优化对该变量进行的检查,因为编译器希望它保持不变时它可能已经改变。

最简单的例子是这样的。假设我们已经声明了一个全局变量为:

int packetsReceived = 0; 

而且它以后像这样使用:

packetsRecieved = 0; 

while (packetsRecieved < 10){ 
    //Wait for more packets 
} 

processPackets(); 

我们绝不会通过回路得到的,因为编译器会说:“嘿,packetsRecieved绝不会被修改在那个循环中,因此它将无限运行。“因此,它会使它成为一个无限循环,因此可以避免每次都检查。

如果我们不是已经声明的变量为:

volatile int packetsRecieved; 

我们告诉这个变量可以随时更改,即使它看起来像它应该保持相同的编译器。所以在我们的例子中,编译器生成的机器码仍然会检查条件,我们的程序将按预期工作。

+1

packetsRecieved如何被另一个线程修改?这只是一个局部变量。另一个线程如何访问它? – JoJo 2015-03-03 17:32:39

+0

好点@JoJo。更新。 – 2015-03-14 19:06:07

7

不,atomicvolatile不是一回事。

atomic(在属性声明中)意味着getter/setter将确保整个值被获取/设置,而不管其他线程可能同时做什么。

volatile是编译器指示变量可以通过其他方式(其他线程,内存映射IO设备)进行修改的指示器,所以它不应该优化(看似)不必要的加载/存储该变量。这与它在Java中的含义相似,尽管Java增加了一些有关内存障碍和C(和Objective-C)不提供的读写顺序的保证。特别是在C中,仅仅声明变量volatile不足以安全地使用它从多个线程wikipedia:volatile variable

0

在不同线程之间共享可变对象可能非常头痛,并且会导致难以追踪的错误。 Objective-c对不可变对象有很大的偏好。我建议如果可能的话,你会找到一种方法来传递不可变对象,如果可能的话。那么你不必担心被写入的共享对象。

相关问题