ARC下如何将目标c对象的地址放入void * volatile *?

发布于 2024-12-23 12:18:32 字数 823 浏览 4 评论 0原文

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

NSManagedObjectContext * moc = nil

现在我需要将其传递到 ARC 环境中的一个函数,该函数接受

void *volatile * value

类型 的参数尝试了

&((__bridge void *)moc))

但出现以下编译器错误

地址表达式必须是左值或函数指针

我也尝试过

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

但收到错误

不兼容的类型转换'NSManagedObjectContext * __strong *' to 'void **' with a __bridge cast

有没有办法先进行强制转换,然后获取强制转换指针的地址?

编辑

更具体地说,我正在尝试实现另一个stackoverflow问题,但我在 ARC 环境中将目标 c NSManagedObjectContext 对象的地址输入到以下函数的第三个参数时遇到问题。

OSAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, void *易失性 *__theValue)

I have a simple objective c object

NSManagedObjectContext * moc = nil

Now I need to pass it into a function in an ARC environment that accepts parameter of type

void *volatile * value

I tried

&((__bridge void *)moc))

but I get the following compiler error

Address expression must be lvalue or a function pointer

I also tried

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

But I get the error

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

Is there any way to first cast and then get the address of the casted pointer?

EDIT

To be more specific, I'm trying to implement the singleton pattern described in another stackoverflow question, but I'm having trouble feeding the address of the objective c NSManagedObjectContext object into the third argument of the following function in an ARC environment.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

宛菡 2024-12-30 12:18:32

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

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

正如你所看到的,如果你去看看源代码 对于dispatch_once,GCD 实现了您在此处寻求实现的相同模式。 GCD 通过不使用 ARC 跟踪指针作为 CompareAndSwaps 的东西,而是使用代理值(此处 pred)来解决您遇到的问题,因此即使您有些厌恶使用对于你的单身人士来说,你可能会考虑模仿他们的方法并使用代理。

也就是说,如果您只在您的情况下使用 GCD,则无需担心诸如粗糙的 ARC 指针转换之类的问题。您还可以合理地确定 GCD 实现在多个平台/体系结构 (MacOS/iOS) 上表现一致。

Another modern singleton pattern I've been seeing/using a lot in the modern era uses GCD's dispatch_once. You asked directly about pointer casting for ARC (and more on that below), but in terms of filling your actual need, why not just do this with GCD? Like this:

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

As you can see if you go look at the source for dispatch_once, GCD implements the same pattern you're seeking to implement here. GCD gets around the problem you're having by not using an ARC-tracked pointer as the thing it CompareAndSwaps, but rather using a surrogate value (here pred), so even if you have some aversion to using GCD for your singleton, you might consider mimicking their approach and using a surrogate.

That said, if you just use GCD for your case, you don't ever have to worry about stuff like gnarly ARC pointer casting. You can also be reasonably sure that the GCD implementation will behave consistently across multiple platforms/architectures (MacOS/iOS).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文