【问题标题】:How to get the address of an objective c object into a void * volatile * under ARC?如何将目标c对象的地址放入ARC下的void * volatile *?
【发布时间】:2011-12-29 18:27:51
【问题描述】:

我有一个简单的目标 c 对象

NSManagedObjectContext * moc = nil

现在我需要将它传递给 ARC 环境中接受类型参数的函数

void *volatile * value

我试过了

&((__bridge void *)moc))

但我得到以下编译器错误

Address expression must be lvalue or a function pointer

我也试过

void ** addr = (__bridge void **)(&moc);

但我得到了错误

Incompatible types casting 'NSManagedObjectContext * __strong *' to 'void **' with a __bridge cast

有没有什么方法可以先强制转换,再获取被强制转换的指针的地址?

编辑

更具体地说,我正在尝试实现另一个 stackoverflow question 中描述的单例模式,但是我无法将目标 c NSManagedObjectContext 对象的地址输入到以下函数的第三个参数中ARC 环境。

OSAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, void *volatile *__theValue)

【问题讨论】:

  • 当我读到它时,在void* 上使用__bridge 可能注定要失败。
  • 嗯,为什么 void * 和 __bridge 互不兼容?
  • 因为__bridge 期望两边都有对象指针。
  • 有没有办法解决这个问题以达到预期的效果?
  • 嗯,阅读文档将是一个不错的起点。

标签: objective-c cocoa pointers casting automatic-ref-counting


【解决方案1】:

我在现代时代经常看到/使用的另一种现代单例模式使用 GCD 的 dispatch_once。您直接询问了 ARC 的指针转换(以及下面的更多内容),但就满足您的实际需求而言,为什么不直接使用 GCD 来做呢?像这样:

+ (NSFoo*)sharedFoo
{
    static dispatch_once_t pred;
    static NSFoo* sFoo;
    dispatch_once(&pred, ^{ sFoo = [[NSFoo alloc] init]; } );
    return sFoo;
}

如果您查看 the source 的 dispatch_once,您会看到,GCD 实现了您在此处寻求实现的相同模式。 GCD 通过不使用 ARC 跟踪指针作为它的 CompareAndSwaps 来解决您遇到的问题,而是使用代理值(此处为pred),所以即使您对使用 GCD 为您的单身人士有些反感,您可以考虑模仿他们的方法并使用代理。

也就是说,如果您只是使用 GCD 来处理您的情况,则不必担心诸如粗糙的 ARC 指针转换之类的事情。您还可以合理地确定 GCD 实现将在多个平台/架构 (MacOS/iOS) 上表现一致。

【讨论】:

    猜你喜欢
    • 2019-11-23
    • 2015-07-24
    • 2013-01-24
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2012-10-01
    相关资源
    最近更新 更多