2011-06-28 96 views
3

我有一個可以同時從多個後臺線程訪問的類。我無法複製課程,因爲它的內容重新創建(處理或記憶方面)可能很昂貴。線程安全保留/釋放

在後臺處理仍在繼續並訪問此屬性時,也可能會替換此類的屬性。

目前我有定期保留/釋放,但它似乎是這種情況(至少在iOS 4),這些是不是線程安全的,因爲即使它們是完美的配對,顯然會發生,retainCount隨機下降,並最終這個類被取消分配。

我正在尋找如何使這個類線程安全的建議,允許併發訪問的屬性和許可證的屬性被修改,而屬性的「早期版本」仍然由一個後臺操作。

+3

不要依賴-retainCount。 –

+0

你保留/釋放什麼? –

回答

6

保留和釋放是原子的。自動釋放不是。按照線程考慮保留;如果線程A持有一個保留(或一個保留/自動釋放),那麼線程A的引用將是有效的,直到該保留被平衡(或自動釋放池被耗盡)。

自動釋放可以從來沒有被用作跨線程所有權轉移原語。

除此之外,很難說沒有更多的代碼,你的應用出了什麼問題。

1

你是在談論一個類或(我想)它的一個實例?

無論如何,保留和釋放應該是線程安全的根據文檔。所以你可能在其他地方有一個bug(這可能會或可能不依賴於iOS 4)。

0

保留/釋放應該足以滿足您的要求。如果你的對象是在兩個線程之間訪問的,那麼他們需要通過一些中間地來訪問這個對象,而且通常它們是同一個線程。

例子:

//Thread 1 Object 

//Setting thread 2's object will occur on the same thread so 
//retains and releases will happen in order with no issue 
thread2Object.atomicObject = self.atomicObject; 

確保你的屬性是原子(線程安全的)意味着只是沒有在財產申報把非原子。如果你決定重寫一個getter或setter,你需要重寫它們並使用你自己的鎖定機制(@ synchronize,NSLock等)。

@propert(retain) NSObject *atomicObject; 
0

一個@property可以聲明爲「原子」,這是默認的,所以它可以安全地從多線程訪問,保證了結果的一致性:

@property (atomic, ...) NSString *someValue; // atomic is the default, thus optional 

它保證在整個執行的getter/setter,來自另一個線程的代碼不會影響結果的一致性。

id val = sharedObject.someValue; 

val結果保留並自動釋放,所以不管其他線程上發生了什麼,val將停留有效期爲當前runloop週期的其餘部分(自動釋放池排出之前)。得到val之後,不能保證sharedObject.someValue將是相同的,因爲另一個線程可以重新分配它。

例子,假設someMethod定期調用在後臺線程取決於你sharedObject

- (void)someMethod { 
    SomeObject *val = sharedObject.someValue; 
    // now, val will remain consistent, 
    // regardless of what happens to sharedObject.someValue 

    [val doSomething]; 
    if (val.someInt > 50) { 
     [val doSomethingElse]; 
    } 
}