You cannot use ARC to manage an object in a struct. L'utente è responsabile del monitoraggio della gestione della memoria manualmente. Sei scoraggiato dal memorizzare oggetti in questo modo.
Se è necessario monitorare la memoria in questo modo, si deve dire ARC che si sta assumendo la responsabilità per l'oggetto quando lo metti nella struct:
context->user_data = CFBridgingRetain([[MYObjCClass alloc] init]);
Questo dice ARC che non è più responsabile è per la oggetto restituito da init
e aggiunge un manuale retain
in modo che context->user_data
sia ora il proprietario.
Quando hai finito con l'oggetto, puoi trasferirlo di nuovo in ARC, oppure puoi rilasciarlo. Per ritrasferirlo su ARC:
MYObjCClass *something = CFBridgingRelease(context->user_data);
context->user_data = NULL;
Ciò indica a ARC che è responsabile per l'oggetto e rimuove il trattenimento. Si dovrebbe NULL il puntatore perché context->user_data
non possiede più questo oggetto e l'oggetto potrebbe scomparire in qualsiasi momento.
Si può anche rilasciare direttamente esso:
CFRelease(context->user_data);
context->user_data = NULL;
Ancora una volta, questa è una tecnica di ultima istanza. In generale non si dovrebbero memorizzare oggetti ObjC nelle strutture dato che ARC non può gestirli.
Come nota a margine, anche se generalmente non raccomando ObjC++, è possibile utilizzare una struct C++ con un distruttore per automatizzarlo. In alcuni casi, potrebbe essere preferibile la gestione della memoria manualmente in C.
fonte
2013-08-14 14:52:24
CFBridgingRetain è uguale a (__bridge_retained void *) e CFBridgingRelease come (__bridge_transfer MYObjCClass *)? – Dmitry
Sì, ma i macro CFBridging * rendono più evidente ciò che sta accadendo. –
Grande. Grazie mille, Rob. Ora è molto chiaro – Dmitry