¿Deberían los IBOutlets ser fuertes o débiles bajo ARC?

Resuelto hypercrypt asked hace 54 años • 11 respuestas

Estoy desarrollando exclusivamente para iOS 5 usando ARC. ¿ Deberían IBOutlets a UIViews (y subclases) ser strongo weak?

La siguiente:

@property (nonatomic, weak) IBOutlet UIButton *button;

Se desharía de todo esto:

- (void)viewDidUnload
{
    // ...
    self.button = nil;
    // ...
}

¿Hay algún problema al hacer esto? Las plantillas se utilizan strongal igual que las propiedades generadas automáticamente y creadas al conectarse directamente al encabezado desde el editor 'Interface Builder', pero ¿por qué? Ya UIViewControllertiene una strongreferencia viewque conserva sus subvistas.

hypercrypt avatar Jan 01 '70 08:01 hypercrypt
Aceptado

ADVERTENCIA, RESPUESTA ACTUALIZADA : esta respuesta no está actualizada según la WWDC 2015; para obtener la respuesta correcta, consulte la respuesta aceptada (Daniel Hall) arriba. Esta respuesta quedará registrada.


Resumido de la biblioteca del desarrollador :

Desde una perspectiva práctica, en iOS y OS X, las salidas deben definirse como propiedades declaradas. Las salidas generalmente deberían ser débiles, excepto las que van desde el propietario del archivo hasta los objetos de nivel superior en un archivo nib (o, en iOS, una escena de guión gráfico), que deberían ser fuertes. Por lo tanto, los puntos de venta que cree normalmente serán débiles de forma predeterminada porque:

  • Los puntos de venta que crea, por ejemplo, subvistas de la vista de un controlador de vista o de la ventana de un controlador de ventana, son referencias arbitrarias entre objetos que no implican propiedad.

  • Las salidas fuertes frecuentemente se especifican mediante clases de marco (por ejemplo, la salida de vista de UIViewController o la salida de ventana de NSWindowController).

    @property (weak) IBOutlet MyView *viewContainerSubview;
    @property (strong) IBOutlet MyOtherClass *topLevelObject;
    
Alexsander Akers avatar Oct 11 '2011 16:10 Alexsander Akers

La mejor práctica recomendada actualmente por Apple es que los IBOutlets sean fuertes a menos que se necesite específicamente un débil para evitar un ciclo de retención. Como Johannes mencionó anteriormente, esto se comentó en la sesión "Implementación de diseños de interfaz de usuario en Interface Builder" de la WWDC 2015, donde un ingeniero de Apple dijo:

Y la última opción que quiero señalar es el tipo de almacenamiento, que puede ser fuerte o débil. En general, debe fortalecer su salida, especialmente si está conectando una salida a una subvista o a una restricción que no siempre será retenida por la jerarquía de vistas. El único momento en el que realmente necesita debilitar una salida es si tiene una vista personalizada que hace referencia a algo de respaldo en la jerarquía de vistas y, en general, eso no se recomienda.

Le pregunté sobre esto en Twitter a un ingeniero del equipo de IB y me confirmó que fuerte debería ser el valor predeterminado y que los documentos para desarrolladores se están actualizando.

https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104

Daniel Hall avatar Jul 14 '2015 00:07 Daniel Hall

Si bien la documentación recomienda usar weakpropiedades para subvistas, desde iOS 6 parece estar bien usarlas strong(el calificador de propiedad predeterminado). Esto se debe al cambio en UIViewControllerel sentido de que las vistas ya no se descargan.

  • Antes de iOS 6, si mantenía enlaces fuertes a las subvistas de la vista del controlador, si la vista principal del controlador de vista se descargaba, esas subvistas se mantendrían mientras el controlador de vista estuviera disponible.
  • Desde iOS 6, las vistas ya no se descargan, sino que se cargan una vez y luego permanecen mientras su controlador esté allí. Así que las propiedades fuertes no importarán. Tampoco crearán ciclos de referencia fuertes, ya que apuntan hacia abajo en el gráfico de referencia fuerte.

Dicho esto, estoy dividido entre usar

@property (nonatomic, weak) IBOutlet UIButton *button;

y

@property (nonatomic) IBOutlet UIButton *button;

en iOS 6 y posteriores:

  • El uso weakindica claramente que el controlador no quiere ser propietario del botón.

  • Pero omitirlo weakno hace daño en iOS 6 sin descargar la vista y es más corto. Algunos pueden señalar que también es más rápido, pero todavía no he encontrado una aplicación que sea demasiado lenta debido a weak IBOutlets.

  • No utilizarlo weakpuede percibirse como un error.

En pocas palabras: desde iOS 6 ya no podemos equivocarnos mientras no utilicemos la descarga de vistas. Tiempo de fiesta. ;)

Tammo Freese avatar Dec 10 '2013 21:12 Tammo Freese