免責事項:この回答のコードはテストされていません。
まず最初に、ほとんどのポインターの使用では、比較と交換が実際には必要ないことを述べたいと思います。C ポインターの読み取りと書き込みは、それ自体がアトミックです。詳細については、この SO の回答を参照してください。同じことがARMにも当てはまります。したがって、アトミックなゲッターとセッターを実装する場合は、他のスレッドが完全に初期化されたオブジェクトを参照できるようにするためのメモリ バリアのみが必要です。
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 が知らないうちに 2 回参照されます。したがって@"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;
}