objective c - punto - Liberación de referencias de objetos de Core Foundation
referencia a objetos autocad 2018 (5)
¿Debo liberar objetos de Core Foundation para borrar la memoria? Y si es así, ¿cómo?
Por ejemplo, en el código:
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);
¿Necesito soltar peopleArray
? ¿Qué pasa con la addressBook
de addressBook
?
Las rules para la administración de memoria en Core Foundation son similares a las de Cocoa: si el método que devuelve una referencia contiene las palabras "crear" o "copiar", usted es el propietario de la referencia y debe llamar a CFRelease()
en esa referencia para renunciar a la propiedad. De lo contrario, no es el propietario de la referencia y debe llamar a CFRetain
para tomar posesión (lo que necesariamente requiere un CFRelease
posterior para abandonar esa nueva propiedad). Estas reglas, tomadas de la Guía de programación de administración de memoria para Core Foundation son:
- Si crea un objeto (ya sea directamente o haciendo una copia de otro objeto (consulte "La regla de creación"), es el propietario del mismo.
- Si obtienes un objeto de otro lugar, no lo posees. Si desea evitar que se elimine, debe agregarse como propietario (con CFRetain).
- Si es el propietario de un objeto, debe renunciar a la propiedad cuando haya terminado de usarlo (con CFRelease).
En su ejemplo, tanto la addressBook
como el peopleArray
deben ser liberados. Dado que no hay un autorelease
equivalente en Core Foundation, si está devolviendo una referencia desde un método, devuelva la matriz sin liberarla. Debería (a menos que sea malvado) incluir "crear" en el nombre del método para indicar a la persona que llama que ahora posee una referencia al objeto devuelto. En este caso, CFArray es un puente gratuito para NSCFArray
, un objeto Objective-C que se hereda de NSObject
. Por lo tanto, puede convertir peopleArray
en un NSArray*
y autorelease
, si necesita devolverlo desde una función / método:
return [(NSArray*)peopleArray autorelease];
Tenga en cuenta que esto solo funciona para las clases puenteadas gratuitas. Tengo entendido que es bastante difícil crear sus propias clases puenteadas gratuitas y solo las clases CF primitivas (string, array, etc.) están puenteadas de forma gratuita, por lo que este enfoque no funcionará siempre. Finalmente, si puede evitar el uso de autorelease
(es decir, puede hacer que la administración de la memoria sea más explícita), probablemente siempre sea algo bueno.
Otro pequeño punto que nadie ha mencionado aún, algunas clases de FQ tienen un "puente gratuito" con su contraparte NS. CFString
y NSString
, NSString
y NSArray
son ejemplos. Esto es relevante, ya que puedes usar la release
con estas clases.
Vea esta otra pregunta de para más información.
Para ARC puedes usar.
return (__bridge_transfer NSArray*)peopleArray;
"__bridge_transfer" transferirá la propiedad a ARC y, por lo tanto, no necesita más llamadas de liberación.
Sí, en CoreFoundation tienes que liberar cualquier cosa con Crear o Copiar en el nombre. Haces esto con CFRelease (). En su caso, debe liberar tanto la matriz como las referencias de la libreta de direcciones.
Sugeriría leer la guide de Apple sobre la administración de memoria de Core Foundation para una discusión en profundidad de esto. También tienen una guía similar para la administración general de la memoria de Cocoa.
Para liberar un objeto CF, debería llamar a la función CFRelease
.