You cannot use ARC to manage an object in a struct. Вы несете ответственность за отслеживание управления памятью вручную. Таким образом вам не рекомендуется хранить объекты.
Если вы должны отслеживать модуля памяти таким образом, вы должны сказать, ARC, что вы принимаете на себя ответственность за объект, когда вы поместите его в структуры:
context->user_data = CFBridgingRetain([[MYObjCClass alloc] init]);
Это говорит ARC, что он больше не отвечает за объект возвращается init
и добавляет руководство retain
, так что context->user_data
теперь является владельцем.
Когда вы закончите с объектом, вы можете либо перенести его обратно в ARC, либо вы можете его отпустить. Чтобы перевести его обратно в ARC:
MYObjCClass *something = CFBridgingRelease(context->user_data);
context->user_data = NULL;
Это говорит, что ARC несет ответственность за объект и удаляет ваше сохранение. Вы должны NULL указатель, потому что context->user_data
больше не владеет этим объектом, и объект может исчезнуть в любое время.
Вы можете также непосредственно освободить его:
CFRelease(context->user_data);
context->user_data = NULL;
Опять же, это последний курорт техника. В общем случае вы не должны хранить объекты ObjC в структурах, поскольку ARC не может их управлять.
В качестве побочного примечания, хотя я обычно не рекомендую ObjC++, для автоматизации этого можно использовать структуру C++ с деструктором. В некоторых случаях это может быть предпочтительнее для управления памятью вручную в C.
CFBridgingRetain то же, что и (__bridge_retained void *) и CFBridgingRelease as (__bridge_transfer MYObjCClass *)? – Dmitry
Да, но макросы CFBridging * делают более очевидным то, что происходит. –
Отлично. Большое спасибо, Роб. Теперь это очень ясно – Dmitry