2012-09-12 26 views
1

預先自動引用計數,您可以在Objective-c中執行相應的指針轉換以允許使用bool OSAtomicCompareAndSwapPtr(void * oldValue,void * newValue,void * volatile * theValue);嘗試在處理多線程訪問時自動交換指針。在啓用了ARC的iOS上使用OSAtomicCompareAndSwapPtr

在ARC下,這些指針轉換無效。 ARC for iOS中是否有等效的原子指針交換?如果這個選擇仍然可用,我希望避免更昂貴的鎖定。

回答

0

如果滿足一個條件,也許你願意玩遊戲,你可以很容易地使用它。

創建一個新文件,將其標記爲未在構建階段使用ARC,並將該交換放入一個小C函數中。在函數的頂部獲取對象的retainCounts,如果它們相同(並且您有理由相信它們不在自動釋放池中),則可以交換它們,因爲ARC將確保每個對象的正確釋放。

如果它們不相同,那麼您可以通過更改保留計數來玩遊戲。

+0

謝謝。不幸的是,這使得依賴於檢查保留計數向交換添加了另一個非線程安全的步驟。考慮到交換的性能優勢,我希望它在遷移到ARC時不會被遺忘。好吧,我會做更多的強化鎖定。 – FooBard

0

聲明:此答案中的驗證碼未經測試!

首先我想提一下,大多數指針的使用並不需要比較和交換。 C指針的讀寫操作本身就是原子的。有關更多詳細信息,請參閱this SO answer。 ARM也一樣。所以,如果你實現原子getter和setter你只需要一個內存屏障,以保證其他線程看到完全初始化的對象:

NSObject * global; 
NSObject * get() { return global; } 
void set(NSObject * value) { OSMemoryBarrier(); global = value; } 

現在回到正題,因爲誰知道,也許有用於比較和實際用途 - 吸引物體。石膏仍然是可能的,你只需要聲明他們現在不同:

NSString * a = @"A"; 
NSObject * b = @"B"; 
OSAtomicCompareAndSwapPtrBarrier(
    (__bridge void *)a, 
    (__bridge void *)b, 
    (__bridge void * *)&a); 

然而這段代碼有問題:字符串@"A"失去參考,並@"B"被引用了兩次,不知道ARC。因此@"A"將會泄漏,並且程序在離開示波器時可能會崩潰,因爲@"B"將被釋放兩次,而只有保留計數器爲1

我認爲唯一的選擇是使用Core Foundation對象。你可以使用NSObject免費橋接CFType的事實。我找不到任何關於這方面的明確文件,但是它來自常識和實際證據。所以例如有可能實現一個單身人士:

CFTypeRef instance; 
Thingamabob * getInstance() { 
    if (!instance) { 
    CFTypeRef t = (__bridge_retained CFTypeRef)[Thingamabob new]; 
    if (!OSAtomicCompareAndSwapPtrBarrier(NULL, t, &instance)) { 
     CFRelease(t); 
    } 
    } 
    return (__bridge Thingamabob *)instance; 
} 
相關問題