将Objective-C对象作为void *指针传递给函数 [英] Pass an Objective-C object to a function as a void * pointer
问题描述
我有一个函数:
myFunction (MyProc callback, void * ref)
此函数在Objective-C类中调用。函数传递一个指向回调的指针(类中的一个函数)和一个引用。引用是必要的,因为回调被静态调用,因此没有上下文。 ref可以用于为回调提供上下文。
This function is called from within an Objective-C class. The function is passed a pointer to the callback (a function in the class) and a reference. The reference is necessary because the callback is called statically and therefore doesn't have a context. The ref can be used to provide a context to the callback.
我想要能够传递Objective-C类作为参考。所以问题是:
I want to be able to pass the Objective-C class as the reference. So the question is:
如何将NSObject转换为void *,以及如何将void *作为NSObject。
How do I cast an NSObject to a void * and how do I cast a void * as an NSObject.
提前感谢。
推荐答案
执行以下操作:
void func(void *q)
{
NSObject* o = CFBridgingRelease(q);
NSLog(@"%@", o);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSObject* o = [NSObject new];
func((void*)CFBridgingRetain(o));
}
return 0;
}
注意 CFBridgingRetain()
和 CFBridgingRelease()
是关于编译器属性的宏。随意使用。我喜欢的API变体,因为它是更常见的使用在我们的代码库,它是更明确/不太混乱。
Note that CFBridgingRetain()
and CFBridgingRelease()
are macros around compiler attributes. Feel free to use either. I like the API variant as it is in more common use in our codebases and it is more explicitly / less confusing.
CFBridgingRetain code>有效地硬保留必须由
有效。 CFBridgingRelease()
平衡的对象。它也碰巧返回 CFTypeRef
,其 与转换兼容 void *
。 CFBridgingRelease()
有效地撤销硬保留,因此 q
c $ c> o
CFBridgingRetain()
effectively hard-retains the object that must be balanced by a CFBridgingRelease()
. It also happens to return a CFTypeRef
which is compatible with a cast to void*
. CFBridgingRelease()
effectively undoes that hard-retain and, thus, q
will only remain valid within the scope that o
is valid.
对基本回调有效,但是你可能不会用 void * context;
类型的东西,必须坚持一段时间。为此:
Valid for basic callbacks, but you'd probably not what that with a void *context;
type thing that has to stick around for a while. For that:
void callback(void *context)
{
// grab an ARC aware reference without impacting hard-retain
NSObject* o = (__bridge NSObject *)(context);
NSLog(@"%@", o);
}
void freeContext(void *context)
{
// release the hard-retain
CFBridgingRelease(context);
}
请注意,Xcode是非常好的建议你应该做什么,如果你离开out调用cast / API调用。它甚至解释了每个替代解决方案的含义(我依赖这一点,直到我可以保持在我的头直)。
Note that Xcode is quite good about suggesting exactly what you should do if you leave out the cast / API call. It even explains the meanings of each of the alternative solutions (I relied on this heavily until I could keep 'em straight in my head).
这篇关于将Objective-C对象作为void *指针传递给函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!