2009-01-19 10 views
24
NSMutableArray *a1 = [[NSMutableArray alloc] init]; 
NSMutableArray *a2 = [NSMutableArray array]; 

TempObj *obj = [[TempObj alloc] init]; //assume this line is repeated for each obj 
[a1 addObject:obj]; 
[a1 addObject:obj2]; 
[a1 addObject:obj3]; 
[a1 addObject:obj4]; 

[obj release]; 
[obj2 release]; 
[obj3 release]; 
[obj4 release]; 

[a1 release]; 

Ok so a2 es un obj de liberación automática, así que no tengo que llamar a la versión en él? Además, ¿cómo sabes cuándo obtienes un objeto de liberación automática?NSMutableArray gestión de la memoria

¿Y para a1, no tengo que recorrer la matriz y soltar cada objeto primero? ¿Qué pasa si llamo [a1 removeAllObjects]; llama eso a [[a1 objectAtIndex: #] release];

¿Se supone que debo liberar esos objetos después de que los haya agregado a la matriz?

Respuesta

45

Cuando agrega un objeto a una matriz, llama al retain en ese objeto. Si no suelta su puntero a ese objeto, será una fuga. Cuando suelte la matriz, llamará al release en todos los objetos que contenga, ya que llamó al retain anteriormente.

En cuanto a liberación automática vs versión, la única manera de saberlo con certeza (aparte de posiblemente leer la documentación) es por el nombre del método. Creo que la regla en general es que si no asignó el objeto, entonces no es responsable de liberarlo.

En cuanto a los métodos de creación de objetos, todos los métodos de conveniencia (array:, arrayWithObjects:, arrayWithArray:, etc.) devuelven objetos liberados automáticamente. Sin embargo, sus métodos de inicio correspondientes (init:, initWithObjects:, initWithArray:, etc.) no: si los llama, usted es responsable de llamar al release en el objeto devuelto.

Parece que recuerdo algunas otras preguntas sobre este tema aquí - puede intentar buscar una explicación más detallada.

+0

haciendo un bucle en todos los objetos y soltando 1 por 1 y que la liberación de llamada en la matriz en sí es incorrecta. – chicken

+4

Eso es correcto: la matriz maneja todo eso por usted. – Andy

+0

me ayudó mucho. ¡Gracias! –

12

Es más fácil pensar en la administración de memoria Objective-C como propiedad que en términos de retener liberación. Cuando agrega los objetos a la matriz, ahora la matriz es copropietaria del objeto y es responsable de gestionarla adecuadamente. Cuando el propietario (cualquier objeto que contenga el código que publicó) llama al release en los objetos, está renunciando a la propiedad y ahora la matriz es el único propietario.

Apple tiene una buena guía sobre cómo funciona la propiedad en Cocoa (incluyendo cómo se sabe cuándo es responsable de llamar al release en un objeto): Memory Management Programming Guide For Cocoa. Es una lectura obligada si quieres usar Cocoa.

0

Lo básico a recordar es esto: debe equilibrar cada llamada a "init", "retener" o "copiar" con una llamada correspondiente a "liberar" o "liberar automáticamente". Eso es todo lo que necesitas saber.

En su ejemplo, a1 tenía una llamada a "init", por lo que debe tener un "lanzamiento" en algún lugar. Ídem con "obj". No llamó a "init", "retener" o "copiar" en ninguna otra cosa, por lo que no necesita llamar "liberar" o "liberar automáticamente" en ninguna otra cosa.

+0

Pero, ¿cuándo lanzo Obj, porque lo agrego a la matriz mutable? ¿Sueldo el obj que creo justo después de agregarlo, porque la matriz crea una copia, o la lanzo cuando la lanzo? – chicken

+0

Lo sueltas tan pronto como ya no necesites hacer nada con él. Una vez que lo haya agregado a la matriz, ya no necesitará hacer nada más con ella, para poder liberarla. La matriz (internamente) necesita mantenerla para que la conserve, pero este es un detalle de implementación interna. –

0

I no sabe ya sea la derecha o mal im

NSMutableArray *a1 = [[NSMutableArray alloc] init]; // will be autorelease 
NSMutableArray *a1 = [NSMutableArray alloc]; // will not autorelease 

después [a1 removeAllObjects];

0

Editásteis obj, obj2, obj3, obj4 justo después de la adición a la matriz (la mejor manera). De lo contrario, tendrías que hacer un bucle y soltar cada objeto (esa es la manera estúpida: la que he hecho hasta ahora).

Cuestiones relacionadas