iPhone-dealloc-Versión vs. nulo
memory memory-management (5)
Preguntándose si alguien con experiencia podría explicar esto un poco más. He visto ejemplos de ...
[view release];
view = nil;
.... dentro del (vacío) dealloc.
¿Cuál es la diferencia y es uno mejor que el otro? ¿Cuál es la mejor manera?
Cuando realizo la prueba de retención de retención, personalmente he visto que nil deja caer un conteo de 3 a 0 para mí, pero la publicación solo lo deja de 3 a 2.
@ bbullis22 has visto que el recuento de restain cae de 3 a 0 porque estableces la referencia en nil. luego solicitaste el recuento de ''nil'' que es cero. sin embargo, el objeto al que solía hacer referencia tiene el mismo recuento de retención - 1 (debido a que la referencia es nula). utilizando la liberación, la referencia todavía hace referencia al mismo objeto, por eso es que ve el recuento de retención caer de 3 a 2 en esta situación.
Creo que usar ambos es una especie de red de seguridad. Con solo el release
en su lugar, podría correr un problema si se atornilla la gestión de recuento de referencias. Liberarías un objeto, devolviendo su memoria al sistema, pero el puntero seguiría siendo válido.
Con nada, tiene la garantía de que el programa no se bloqueará, ya que enviar un mensaje a nil
no hace nada.
En cuanto al uso dentro de su código, en su dealloc
no necesita la asignación a la propiedad, lo único que tiene que hacer es dealloc
.
- (void)dealloc {
[myProperty release]; // don''t need to assign since you won''t have the object soon anyway
[super dealloc];
}
Lo que has visto es probablemente esto:
1) [foo release];
2) self.bar = nil;
3) baz = nil;
Está liberando el objeto, accediéndolo a través de la variable de instancia
foo
. La variable de instancia se convertirá en un puntero colgante. Este es el método preferido en dealloc.Es asignar
nil
a unabar
propiedades en sí mismo, que en la práctica liberará lo que la propiedad retenga actualmente. Haga esto si tiene un configurador personalizado para la propiedad, que se supone que debe limpiar más que solo la variable de instancia que respalda la propiedad.Sobreescribirá el puntero
baz
haciendo referencia al objeto con nil, pero no liberará el objeto. El resultado es una pérdida de memoria. Nunca hagas esto
Si no está usando propiedades (donde self.property = nil también liberará un objeto), SIEMPRE debe seguir un lanzamiento por código que establezca la referencia como nula, como lo describió a continuación:
[view release]; view = nil;
La razón es que evita la posibilidad de que se pueda usar una referencia que no sea válida. Es raro y difícil que suceda, pero puede ocurrir.
Esto es aún más importante en viewDidUnload, si está liberando IBOutlets: ese es un escenario más realista donde una referencia podría fallar debido a advertencias de memoria descargando una vista, y luego algún otro código en la vista tratando de hacer uso de una referencia antes del la vista es recargada
Básicamente es solo una buena práctica y te ahorrará un choque en algún momento si lo haces como un hábito para hacer esto.