usos sistema programacion origen operativo lenguaje caracteristicas apple iphone objective-c xcode release retain

iphone - sistema - Lanzamiento de objetivo C, autorelease y tipos de datos



swift versions (3)

Soy nuevo en el código administrado por memoria, pero tengo la idea bastante bien.

Al pasar mi aplicación a través de la herramienta de fugas en XCode, me di cuenta de que solo tenía que limpiar mis objetos personalizados, pero no arrays creados dinámicamente, por ejemplo, así que pensé que esos tipos de datos son liberados automáticamente, tiene sentido ya que solo tuve que liberar los arrays Utilicé como propiedades que tenían un (retener) en ellos.

Entonces me di cuenta de algo peculiar: estaba goteando una cierta matriz inicializada de esta manera:

NSMutableArray *removals = [NSMutableArray new];

pero no similar

NSMutableArray *removals = [NSMutableArray arrayWithCapacity:9];

Ahora, la razón por la que uno se configuró con "nuevo" es que podría tener de 0 a 99 elementos, mientras que el otro sabía que siempre iba a ser 9. Ya que ambas matrices se pasan al mismo método más adelante según el usuario interacción, me estaba saliendo una fuga si no lo liberé al final del método, o una excepción si lo hice.

Cambié la primera matriz a

NSMutableArray *removals = [NSMutableArray arrayWithCapacity:99];

Y no tengo fugas y no tengo que liberar nada. ¿Alguien puede explicar?


Así es como se implementan las cosas detrás de escena:

+(NSMutableArray*) new { return [[NSMutableArray alloc] init]; }

y

+(NSMutableArray*) arrayWithCapacity:(NSNumber)capacity { return [[NSMutableArray alloc] initWithCapacity:capacity] **autorelease**]; }

En el primer caso, la matriz está asignada solo y usted es responsable de desasignarla. Por el contrario, arrayWithCapacity se ha lanzado automáticamente para usted y no provocará fugas, incluso si se olvida de desasignar.


Como se indica en las reglas de administración de la memoria , siempre que tenga un objeto que haya creado con +alloc , +new , -mutableCopy o -mutableCopy , lo posee y es responsable de liberarlo en algún momento. (De hecho, +new es solo una abreviatura de [[MyClass alloc] init] .) Como se señaló, crear una matriz a través de [NSArray new] sin liberarla es una pérdida de memoria. Sin embargo, si maneja este objeto correctamente, generalmente es posible liberarlo en algún momento. Por ejemplo:

  • Si se llama al método que utiliza la matriz desde dentro del método que crea la matriz, entonces debería poder liberar la matriz después de que se haya utilizado. Si el método interno necesita mantener una referencia más permanente a la matriz alrededor, entonces ese método es responsable de enviar - -retain y, finalmente, - -release al objeto. Por ejemplo:

    - (void)myMethod { NSArray *removals = [NSArray new]; // ... [someObject someOtherMethod:removals]; [removals release]; }

  • Si creó la matriz en un método -init para un objeto, entonces el método -dealloc puede liberarlo cuando se destruye el objeto.

  • Si necesita crear la matriz y luego devolverla desde el método, ha descubierto la razón por la que se inventó la liberación automática. La persona que llama a su método no es responsable de liberar el objeto, ya que no es un +alloc , +new , -mutableCopy o -mutableCopy , pero debe asegurarse de que se libere finalmente. En este caso, usted llama manualmente a -autorelease en el objeto antes de devolverlo. Por ejemplo:

    - (NSArray *)myMethod { NSArray *removals = [NSArray new]; // ... return [removals autorelease]; }

Cuando crea la matriz a través de +arrayWithCapacity: no está llamando a uno de los métodos "especiales", por lo que no tiene que liberar el resultado. Esto probablemente se implementa con -autorelease , como el último ejemplo anterior, pero no necesariamente. (Por cierto, también puede crear un NSMutableArray vacío lanzado automáticamente con [NSMutableArray array] ; el método se encuentra en NSArray, por lo que no aparecerá en la documentación bajo NSMutableArray, pero creará un array mutable cuando se envíe a la clase NSMutableArray .) Si va a devolver la matriz desde su método, puede usar esto como una abreviatura para [[[NSMutableArray alloc] init] autorelease] pero es solo un acceso directo. Sin embargo, en muchas situaciones, puede crear un objeto con -init o +new y liberarlo manualmente en el momento adecuado.


El cacao utiliza ciertas convenciones de nomenclatura. Cualquier cosa que comience con alloc, new o copy devuelve algo con un retenerCount de 1 y se le exige que libere. Cualquier otra cosa que devuelva una función tiene una cuenta de retención equilibrada (podría estar sujeta a otra cosa, o podría retenerse y liberarse).

Asi que:

NSMutableArray *removals = [NSMutableArray new];

Tiene un recuento de 1, y:

NSMutableArray *removals = [NSMutableArray arrayWithCapacity:99];

o

NSMutableArray *removals = [NSMutableArray array];

No, ya que los métodos no son prefijados con alloc, new o copy. Todo esto se explica en la documentation gestión de memoria. En particular:

Usted es el propietario de un objeto si lo crea con un método cuyo nombre comience con “alloc” o “new” o contenga “copy” (por ejemplo, alloc, newObject, o mutableCopy), o si le envía un mensaje de retención. Usted es responsable de renunciar a la propiedad de los objetos que posee mediante el lanzamiento o la liberación automática. En cualquier otro momento en que reciba un objeto, no debe liberarlo.