预自动引用计数,您可以在 Objective-c 中进行适当的指针转换,以允许您使用 bool OSAtomicCompareAndSwapPtr(void* oldValue, void* newValue, void* volatile *theValue); 在处理多线程访问时尝试原子交换指针。
在 ARC 下,这些指针转换无效。ARC for iOS 下是否有等效的原子指针交换?如果这种替代方案仍然可用,我希望避免更昂贵的锁定。
预自动引用计数,您可以在 Objective-c 中进行适当的指针转换,以允许您使用 bool OSAtomicCompareAndSwapPtr(void* oldValue, void* newValue, void* volatile *theValue); 在处理多线程访问时尝试原子交换指针。
在 ARC 下,这些指针转换无效。ARC for iOS 下是否有等效的原子指针交换?如果这种替代方案仍然可用,我希望避免更昂贵的锁定。
如果满足一个条件,或者如果您愿意玩游戏,您也许可以轻松使用它。
创建一个新文件,在构建阶段将其标记为不使用 ARC,并将此交换放入一个小的 C 函数中。在函数的顶部获取对象的 retainCounts,如果它们相等(并且您有理由相信它们不在自动释放池中),您可以交换它们,因为 ARC 将确保对每个对象进行正确的释放。
如果它们不相等,那么您可以通过更改保留计数来玩游戏。
免责声明:此答案中的代码未经测试!
首先我想提一下,大多数指针的使用并不真正需要比较和交换。C 指针读取和写入本身是原子的。有关更多详细信息,请参阅此 SO 答案。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;
}