2011-03-17 49 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對不可變對象有很大的偏好。我建議如果可能的話,你會找到一種方法來傳遞不可變對象,如果可能的話。那麼你不必擔心被寫入的共享對象。

相關問題