2009-03-09 8 views
9

Esto no es una basura recogida ambienteConfiguración de un objeto nulo en comparación con la liberación + realloc

Tengo una variable de instancia de clase que en algún momento de mi tiempo de ejecución, lo que necesito para volver a inicializar con un conjunto de datos diferente de lo que era originalmente construido con.

Hipotéticamente hablando, lo que si tengo una NSMutableArray o un NSMutableDictionary, sería más eficiente para hacer algo como:

[myArr release]; 
myArr = [[NSMutableArray alloc] init....]; 

o simplemente,

myArr = nil; 

Will myArr liberar el objeto y dejarme sin un puntero al almacenamiento en la memoria para que pueda volver a utilizar myArr?

Respuesta

21

Si hace myArr=nil; solo, ha perdido el puntero al que puede enviar el mensaje release. No hay magia para release su objeto.

Y, como dice Georg, sin poder liberar su objeto, esa memoria se 'ha filtrado'.

+1

Y no es la pérdida de memoria. –

1

Una forma de darse cuenta de la diferencia podría ser esta: Establecer una referencia a un objeto como nulo no le hace nada al objeto, solo hace algo con la referencia.

"Liberar el objeto" no es "nada", por lo que no hace eso. :) En un lenguaje recogido de basura, puede hacer eso como un efecto secundario de descartar la referencia, pero en Objective C no funciona de esa manera.

5

Si se va en Mac OS, no iPhone OS yo diría que depende de si el recolector de basura se activa o no:

  • con GC: El uso myArr = nil;
  • sin GC: utilizar [myArr release];

Desafortunadamente, en iPhone, no hay recolección de basura, por lo que si no quiere pérdidas de memoria, debe liberar su objeto una vez que ya no lo necesite.

+0

Sin GC en iPhone. – Abizern

+0

Sí, tienes razón. Estoy demasiado centrado en Mac OS ... Mi respuesta está actualizada. – mouviciel

+0

Ni siquiera necesita establecerlo en cero, ya que esto ocurre principalmente en el código dealloc cuando se recoge el objeto superior con todos sus enlaces. –

6

Puede usar una propiedad y obtener casi la sintaxis que desee sin la pérdida de memoria.

Utilice esta sintaxis para declarar la matriz

@property (readwrite, retain) NSMutableArray *myArray; 

A continuación, vuelva a inicializar así:

[self setMyArray:[NSMutableArray array]]; 
+0

O para usar la sintaxis de propiedad de punto: self.myArray = [NSMutableArray array]; –

+0

como myArray apunta a un objeto mutable, una mejor forma sería @property (readwrite, copy) NSMutableArray * myArray – Abizern

1

Si lo que se desea es restablecer el contenido de un NSMutableArray/NSMutableDictionary, puede también llame a removeAllObjects y tiene una nueva matriz/dict para trabajar.

4

El primer bloque de código está bien. Sin embargo, el segundo bloque no te deja con una matriz que puedes usar, por lo que no es suficiente. La mitad de la corrección de ese bloque, creo que decir:

myArr = nil; 
myArr = [[NSMutableArray alloc] init....]; 

Sin embargo, esto no lograr lo que desea, ya sea porque no se está liberando myArr.Si ha sintetizado un setter para myArr, entonces puede obtener el comportamiento de liberación que desee establecer en cero, utilizando el setter (self.myArr) en lugar de acceder al puntero directamente (myArr). La corrección de su segundo bloque completo:

self.myArr = nil; 
myArr = [[NSMutableArray alloc] init....]; 

Ahora tenemos ejemplos de código equivalentes, utilizando una incubadora con cero a la liberación, el otro no. Ellos son lo mismo.

Si myArr es una matriz mutable como en estos ejemplos, el método más eficaz es utilizar removeAllObjects, evitando todo el trabajo de liberar la memoria sólo para reclamar su devolución:

[myArr removeAllObjects]; 
+0

Re # 2: Además, puede usar el setter con la nueva matriz también (pasando una matriz autorrebelada, '[NSMutableArray array] '), y luego use accesadores de array para completarlo. http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ModelObjects/Articles/moAccessorMethods.html Por supuesto, si vas a poblar la nueva matriz inmediatamente, sería más eficiente hacer que con la nueva matriz en una variable local, establezca la propiedad en la matriz terminada. Y cualquiera de estos métodos no requeriría establecer la propiedad a 'nil' primero. –

Cuestiones relacionadas