objective-c - guia - fragatas modernas
Objective-C Diferencia entre establecer nulo y liberar. (4)
He aprendido que en dealloc
haces [object release];
pero en viewDidUnload
(en una subclase UIViewController) haces self.object = nil
. ¿Cuál es realmente la diferencia porque self.object = nil
(asumimos que el objeto es una (nonatomic, retain)
) retiene nil
(que no hace nada) y luego libera el valor antiguo y luego el recuento de referencia es 0, verdad?
Si acaba de liberar un objeto, se convertirá en objeto liberado.
Y si intenta realizar cualquier tipo de operación en un objeto liberado, su aplicación se bloquea. Para evitar este tipo de accidentes, siempre se prefiere "asignar su objeto a cero después de liberarlo". Porque todos sabemos que cualquier operación realizada en nil no se ejecutará :)
Si haces object = nil
sin [object release]
, eso podría causar pérdida de memoria. Si lo hace [object release]
sin object = nil
después, el objeto se convierte en un puntero colgante como se sugiere en @Jim. self.object = nil
es un azúcar para la llamada de la función de establecedor.
Si lo hace [liberación de objeto], y desea acceder al objeto, la aplicación simplemente se bloquea. Si haces object = nil, y quieres acceder al objeto, nada funcionará.
El motivo está en [liberación de objeto], se intenta liberar el objeto. por lo que no tiene ningún puntero (sin memotia). En el object = nil,
se intenta asignar el objeto con un puntero nulo. así que si tratas de acceder al objeto no pasará nada.
Generalmente escribimos el código como [ object release]; object = nil;
object release]; object = nil;
porque si accedes al objeto inesperadamente, la aplicación no se bloquea.
self.object = nil
llama a su configurador, que liberará el valor anterior, establecerá el miembro en nil
y posiblemente hará otras cosas (es un método, por lo que podría hacer cualquier cosa). La parte de "cualquier cosa" es potencialmente peligrosa; Vea esta pregunta , por ejemplo.
[object release]
libera el valor antiguo, pero deja al miembro como un puntero ahora colgando, lo que es una buena receta para los errores. En dealloc
realmente no importa, ya que el puntero en sí también está a punto de desaparecer, pero en cualquier otro caso es una muy mala idea liberar un miembro sin configurarlo en nil
.
(Como una nota al margen, nunca debe asumir que soltar un objeto le da un recuento de referencia de 0. Libera su referencia, pero otros objetos pueden tener referencias a él).