我有一個Objective-C類,有一個NSMutableDictionary作為實體變數。當這個字典在另一個執行緒中被突變時,它偶爾會從一個執行緒中被讀取,從而導致崩潰。我的類看起來是這樣的:
@interface MyClass。NSObject {
NSMutableDictionary sharedState。
}
@end
@implementation MyClass
- (instancetype) init {
self = [super init] 。
if (self != nil) {
[self reinitialize] 。
}
return self;
}
- (void) reinitialize {
sharedState = [[NSMutableDictionary alloc] init]。
}
@end
還有一些方法從sharedState中讀取或變異。reinitialize方法是唯一一個實際分配指標的地方,但是除了初始化器之外,還有一些方法呼叫reinitialize。
為了解決我的執行緒問題,我正在考慮將sharedState的所有使用,包括reinitialize中的使用,包裝在
@synchronized (sharedState) {
...
}
因為它很直接,而且在實踐中,性能上的沖擊不應該是一個問題。然而,特別是在reinitialize中,我將在一個甚至還沒有被alloc的實體變數上進行同步,而在隨后的呼叫中,我將重新分配我正在同步的指標。這是否有效和安全?還是說我應該在self上進行同步?
uj5u.com熱心網友回復:
這里有一些想法:
nil,所以你會做@synchronized(nil),這可能會干擾你代碼中做類似事情的其他部分,這可能會在你代碼的其他部分產生競賽條件@synchronized塊中替換的物件上@synchronize,這將使你避免資料競賽的努力化為泡影如果你想保護你的類的成員,那么是的,的確,@synchronizd(self)會更好、更安全,這里的規則是在你想保護的值的上面一層進行同步,除非你101%確定指標永遠不會改變,在這種情況下你可以在成員上進行同步,但是在你的代碼中似乎不是這樣。
只要確保你包裹所有對sharedState的訪問,這實際上是主要的挑戰,以確保你添加的新方法不會自己產生競賽條件。
uj5u.com熱心網友回復:
@synchronized (nil)應該不會阻止什么,但仍然是一個可能的信號燈,因為當信號燈為nil時,它仍然有一個唯一的地址。在nil的情況下,只是不夠獨特。對于這一點,我認為它可能會導致未定義的行為。
。
NSObject *object = nil。
@synchronized (object) {
NSLog(@"address? %p", object)。
}
semaphore的想法是提供一些唯一的識別符號。
docs只是說。
它可以防止不同的執行緒在同一時間獲取同一個鎖
而且
為了保護代碼段不被多個執行緒同時執行,Objective-C提供了@synchronized() 指令。
@synchronized() 指令鎖定一段代碼,供一個執行緒使用。其他執行緒被阻斷,直到該執行緒退出受保護的代碼--也就是說,當執行繼續超過@synchronized()塊中的最后一條陳述句時。
你也可以創建你自己的信號燈,它仍然可以作業。
static void *somevalue = &somevalue; @synchronized (somevalue) { ///一個執行緒同時在這個代碼塊上作業。。 }它并沒有鎖定值,而是鎖定了被包圍的代碼塊,使其不能被其他執行緒訪問,直到該代碼塊被離開/解鎖。
但是當你使用
self作為mutex/mutual exclusion semaphore時,你實際上鎖定了類,因為只有一個類物件存在,它被所有物件共享。因此,如果你想超級安全,沒有其他方法可以在同一地址空間作業,你確實可以使用
@synchronized (self),讓類中只有一個方法在同步塊的行程時間內作業。但是由于你的物件是你的類的內部成員,你也可以提供一個適當的getter方法來使外部訪問安全,例如,通過復制。這取決于用例是否符合你的需求。
-(NSMutableDictionary*)shareStateCopy { return [sharedState copy]; //actually [. mutableCopy]/span> }轉載請註明出處,本文鏈接:https://www.uj5u.com/net/307433.html
標籤:
