ios - IBOutlet y viewDidUnload bajo ARC
weak-references automatic-ref-counting (5)
A partir de iOS 5 y OS X 10.7, weak
producirá un puntero a cero automático. Esto significa que cuando se suelta el objeto puntiagudo, el puntero se configura automá- ticamente en nil
(para más información, consulte Cero Referencias débiles en ARC ).
Por lo tanto, en iOS 5+ y OS X 10.7+, no es útil establecer las propiedades de IBOutlet
weak
en nil
manualmente en el método viewDidUnload
: cuando se descarga la vista principal, se publicarán todas sus subvistas, por lo que se establecen las propiedades relacionadas a nil
.
Aquí hay una pregunta similar sobre here , sin embargo, solo quiero aclarar algo que no fue completamente explicado allí.
Entiendo que todos los delegados y puntos de venta, de hecho, cualquier referencia a un objeto "padre", para ser un buen ciudadano y pensar en el gráfico de objetos por un minuto, debe poner a cero las referencias débiles. Debido a la naturaleza de la puesta a cero de punteros débiles que caen automáticamente a cero en el recuento de retención del objeto al que se hace referencia que llega a cero, ¿significa esto que ahora no es necesario establecer IBOutlets en nil en viewDidUnload
?
Entonces, si declaro mi outlet así:
@property (nonatomic, weak) IBOutlet UILabel *myLabel;
¿El siguiente código tiene algún efecto?
- (void)viewDidUnload
{
self.myLabel = nil;
[super viewDidUnload];
}
Desde mi entendimiento de cómo se administran los puntos de venta en ARC si está utilizando una referencia débil, no necesita agregar nada para verDidUnload ya que será nulo. Hacerlo es por lo tanto redundante.
Sin embargo, si tiene puntos de venta fuertes, lo que Apple dice que debe hacer si está apuntando a un elemento de nivel superior en el plumín, entonces definitivamente debe continuar agregando la línea apropiada en viewDidUnload para anular estos.
Hice viewDidUnload
pruebas y parece que el código en el método viewDidUnload
es innecesario. Para respaldar esto, los documentos para viewDidUnload
realmente dicen:
Cuando se llama a este método, la propiedad de vista es nula.
Indicando que la referencia débil debe haberse configurado en nil
automáticamente.
Solo haciendo un poco de investigación ...
Como yo lo entiendo, débil es similar a asignar, en el sentido de que ambas son referencias débiles.
Sin embargo, asignar no crea una referencia cero. es decir, si el objeto en cuestión se destruye y usted accede a esa propiedad, obtendrá un BAD_ACCESS_EXCEPTION
.
Las propiedades débiles se ponen a cero automáticamente (= nil) cuando se destruye el objeto al que hace referencia.
En ambos casos, no es necesario establecer la propiedad en cero, ya que no contribuye al recuento de retención del objeto en cuestión. Es necesario cuando se usan propiedades de retención.
Aparentemente, ARC también presenta una nueva propiedad "fuerte", que es lo mismo que "retener"?
Investigación hecha here
Tengo alguna evidencia empírica para apoyar que IBOutlets ya están configurados en nil automáticamente. Esto es lo que hice:
- Configuré ivars explícitos para mis propiedades IBOutlet (
@synthesize myLabel = myLabel_
) para que luego pueda inspeccionar sus valores en el depurador. -
viewDidUnload
un punto de interrupción en la primera línea deviewDidUnload
. -
viewDidUnload
queviewDidUnload
fuera llamado simulando una advertencia de memoria. - Inspeccioné los valores de los ivars explícitos que asocié con mis propiedades de IBOutlet.
Los ivars explícitos todos tenían nil
como su valor, luego llegué al punto de interrupción.