El método dealloc
nunca es llamado directamente. Todo se hace a través del mecanismo retain
/release
(y el principio de recuento de referencias). Así que este es el método release
que se llama, no el dealloc
directamente.El método de ejecución dealloc
solo es invocado por el motor de ejecución si la última llamada release
hace que el recuento de referencias (retainCount) del objeto llegue a cero, lo que significa que el objeto realmente se desasigna de la memoria ya que nadie lo usa.
NSArray
y todas las clases de contenedores en Cocoa (NSDictionary
, NSSet
, ...) conservan sus valores. Entonces, cuando agrega un objeto a un contenedor como NSArray
, será retain
ese valor. Y cuando se quita ese valor (incluyendo cuando se llama removeAllObjects ") se release
que
reglas Mgmt memoria son fáciles de seguir:., Pero la única regla que importa es que usted sólo tiene que llamar release
o autorelease
si se llama alloc
, retain
o copy
métodos. Eso es siempre la responsabilidad del objet el que hizo la alloc
/retain
/copy
a llamar a la release
/autorelease
. Nunca deje a un alloc
/retain
/copy
sin espera de llamada release
/autorelease
para equilibrarlo (o usted tendrá fugas), pero por otro lado nunca llame al release
/autorelease
si no hizo la llamada alloc
/retain
/copy
.
Buena ejemplo 1:
MyClass* obj = [[MyClass alloc] init]; // here you do an alloc
[myArray addObject:obj]; // the NSArray "myArray" retains the object obj
// so now you can release it, the array has the responsability of the object while it is held in the array
[obj release]; // this release balance the "alloc" on the first line, so that's good
[myArray removeAllObjects]; // there the object held by the array receive a release while being removed from the array. As nobody retains it anymore, its dealloc method will be called automatically.
Buena ejemplo 2:
MyClass* obj = [[MyClass alloc] init]; // here you do an alloc
[myArray addObject:obj]; // the NSArray "myArray" retains the object obj
// so now you can release it, the array has the responsability of the object while it is held in the array
[myArray removeAllObjects]; // there the object held by the array receive a release while being removed from the array. But your own code still retains a reference to it (because of the "alloc" on first line) so it won't be removed from memory right now
[obj release]; // this release balance the "alloc" on the first line, and as nobody retains the object anymore, its dealloc method will be called and it will be deallocated from memory
Buena ejemplo 3:
MyClass* obj = [self getSomeObjectFromAnotherMethod]; // here you don't have an "alloc" on this line
[myArray addObject:obj]; // the array retains the object
[myArray removeAllObjects]; // the array release the object while it removes it from the array
// no need to call "release" here as there is no "alloc" done in the scope of this code
Mal ejemplo:
MyClass* obj = [self getSomeObjectFromAnotherMethod]; // here you don't have an "alloc" on this line
[myArray addObject:obj]; // the array retains the object
[myArray removeAllObjects]; // the array release the object while it removes it from the array
[obj release]; // Crash here! obj does not exists anymore and has been deallocated from memory before this line!
Nadie debe llamar 'dealloc' que no sea el administrador de memoria (o' dealloc' de una subclase). 'removeAllObjects' llama a' release' en cada objeto, ya que lo borra de la matriz. –
sí, si ve un 'dealloc' en su código que no es parte de' [super dealloc]; 'lo está haciendo mal. –