Do something like this:
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;
}
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()
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.
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);
}
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).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…