Ответ 1
Сделайте что-то вроде этого:
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-вариант, поскольку он более распространен в наших кодовых базах, и он более явно/менее запутан.
CFBridgingRetain()
эффективно удерживает объект, который должен быть сбалансирован с помощью CFBridgingRelease()
. Также происходит возврат a CFTypeRef
, который совместим с приведением в void*
. CFBridgingRelease()
эффективно отменяет сохранение и, следовательно, q
останется действительным только в пределах области действия o
.
Действует для базовых обратных вызовов, но вы, вероятно, не знаете, что с тегом типа void *context;
, которое нужно придерживаться некоторое время. Для этого:
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 неплохо говорит о том, что вы должны делать, если не выполняете вызов cast/API. Это даже объясняет значения каждого из альтернативных решений (я полагался на это сильно, пока не смог удержать их прямо в моей голове).