Establecer un objeto nil versus release + realloc

votos
9

Este no es un ambiente recolectado basura

Tengo una variable de instancia de clase que, en algún momento de mi tiempo de ejecución, necesito reinicializar con un conjunto de datos diferente del que se construyó originalmente.

Hipotéticamente hablando, ¿qué pasa si tengo una NSMutableArrayo una NSMutableDictionary, sería más eficiente hacer algo como:

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

o solo,

myArr = nil;

¿MyArr liberará el objeto y me dejará sin un puntero al almacenamiento en la memoria para que pueda volver a utilizar myArr?

Publicado el 09/03/2009 a las 17:03
fuente por usuario
En otros idiomas...                            


6 respuestas

votos
21

Si lo haces myArr=nil;solo, has perdido el puntero al que puedes enviar el releasemensaje. No hay magia para releasetu objeto.

Y, como dice Georg, sin poder liberar su objeto, esa memoria se 'filtró'.

Respondida el 09/03/2009 a las 17:07
fuente por usuario

votos
6

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

Usa esta sintaxis para declarar la matriz

@property (readwrite, retain) NSMutableArray *myArray;

A continuación, reinícielo de esta manera:

[self setMyArray:[NSMutableArray array]];
Respondida el 09/03/2009 a las 17:59
fuente por usuario

votos
5

Si estuvieras en Mac OS, no en iPhone OS, diría que depende de si el recolector de basura está activado o no:

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

Desafortunadamente, en el 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.

Respondida el 09/03/2009 a las 17:13
fuente por usuario

votos
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. Medio corregir ese bloque, creo que quieres decir:

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

Sin embargo, esto tampoco logra lo que quieres porque no estás 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). Corregir completamente tu segundo bloque:

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

Ahora tenemos ejemplos de código equivalentes, uno que usa setter con nil para liberar, el otro no. Ellos son lo mismo.

Si myArr es una matriz mutable como en estos ejemplos, el método más eficiente es usar removeAllObjects, evitando todo el trabajo de liberar memoria solo para recuperarla:

[myArr removeAllObjects];
Respondida el 02/12/2009 a las 11:08
fuente por usuario

votos
1

Si lo que desea es restablecer el contenido de un NSMutableArray / NSMutableDictionary, también puede llamar a removeAllObjects y tiene un nuevo array / dict con el que trabajar.

Respondida el 13/03/2009 a las 22:37
fuente por usuario

votos
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.

Respondida el 09/03/2009 a las 17:09
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more