Estoy desarrollando exclusivamente para iOS 5 usando ARC. En caso IBOutletes que UIViews (y subclases) sea strongo weak?
El seguimiento:
@property (nonatomic, weak) IBOutlet UIButton *button;
Se desharía de todo esto:
- (void)viewDidUnload
{
// ...
self.button = nil;
// ...
}
¿Hay algún problema para hacer esto? Las plantillas se utilizan al strongigual que las propiedades generadas automáticamente que se crean al conectarse directamente al encabezado desde el editor 'Interface Builder', pero ¿por qué? El UIViewControllerya tiene una strongreferencia a su viewque conserva sus subvistas.

IBOutletCollection()no debe serweak, de lo contrario vuelve comonil.strongRespuestas:
La mejor práctica actual recomendada por Apple es que los IBOutlets sean fuertes a menos que sean débiles específicamente necesarios 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 el generador de interfaces" de WWDC 2015, donde un ingeniero de Apple dijo:
Le pregunté sobre esto en Twitter a un ingeniero del equipo del IB y él confirmó que fuerte debería ser el valor predeterminado y que los documentos del desarrollador se están actualizando.
https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104
fuente
ADVERTENCIA, RESPUESTA ACTUALIZADA : esta respuesta no está actualizada según WWDC 2015, para la respuesta correcta consulte la respuesta aceptada (Daniel Hall) arriba. Esta respuesta quedará registrada.
Resumido de la biblioteca del desarrollador :
fuente
Si bien la documentación recomienda usar
weakpropiedades en subvistas, desde iOS 6 parece estar bien usarstrong(el calificador de propiedad predeterminado) en su lugar. Eso es causado por el cambio enUIViewControllerque las vistas ya no se descargan.Dicho esto, estoy dividido entre usar
y
en iOS 6 y posterior:
El uso
weakindica claramente que el controlador no desea la propiedad del botón.Pero omitir
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 aún no he encontrado una aplicación que sea demasiado lenta debido aweakIBOutlets.No usar
weakpuede ser percibido como un error.En pocas palabras: desde iOS 6 ya no podemos equivocarnos mientras no usemos la descarga de vista. Tiempo de fiesta. ;)
fuente
nilmanual.weakes un poco más barato en ARM64: Dweakpropiedades o las__weakvariables de instancia son el camino a seguir. Solo quería señalar que hay menos posibilidades de error aquí. En cuanto aweakser más barato en arm64, ni siquiera he visto un problema de rendimiento en la vida real conweakIBOutlets en armv7. :)strongtiene sentido también.strongsolo es perjudicial si usa la descarga de vistas, pero ¿quién lo hace en estos días? :)No veo ningún problema con eso. Antes del ARC, siempre he hecho mis IBOutlets
assign, ya que sus supervistas ya los retienen. Si los haceweak, no debería tener que anularlos en viewDidUnload, como señala.Una advertencia: puede admitir iOS 4.x en un proyecto ARC, pero si lo hace, no puede usar
weak, por lo que tendría que hacerlosassign, en cuyo caso aún querría anular la referenciaviewDidUnloadpara evitar Un puntero colgante. Aquí hay un ejemplo de un error de puntero colgante que he experimentado:Un UIViewController tiene un UITextField para el código postal. Utiliza CLLocationManager para revertir la geocodificación de la ubicación del usuario y establecer el código postal. Aquí está la devolución de llamada delegada:
Descubrí que si descartaba esta vista en el momento adecuado y no había cerrado self.zip
viewDidUnload, la devolución de llamada delegada podría generar una excepción de acceso incorrecto en self.zip.text.fuente
weakno es necesario incluir las propiedadesviewDidUnload. Pero, ¿por qué la plantilla de Apple para crear puntos de venta incluye un[self setMySubview:nil]?IBOutletdebe ser fuerte, por razones de rendimiento. Consulte Referencia del guión gráfico, IBOutlet fuerte, Escena Dock en iOS 9A partir de Xcode 7, sugiere
strongSi ve la sesión 407 de WWDC 2015 Implementando diseños de UI en Interface Builder , sugiere (transcripción de http://asciiwwdc.com/2015/sessions/407 )
fuente
En el desarrollo de iOS, la carga de NIB es un poco diferente del desarrollo de Mac.
En el desarrollo de Mac, un IBOutlet suele ser una referencia débil: si tiene una subclase de NSViewController, solo se conservará la vista de nivel superior y cuando desactive el controlador, todas sus subvistas y salidas se liberarán automáticamente.
UiViewController utiliza la codificación de valor clave para establecer los puntos de venta utilizando referencias fuertes. Por lo tanto, cuando desasigna su UIViewController, la vista superior se desasigna automáticamente, pero también debe desasignar todas sus salidas en el método de desasignación.
En esta publicación de Big Nerd Ranch , cubren este tema y también explican por qué usar una referencia fuerte en IBOutlet no es una buena opción (incluso si Apple lo recomienda en este caso).
fuente
Una cosa que quiero señalar aquí, y es que, a pesar de lo que los ingenieros de Apple han declarado en su propio video WWDC 2015 aquí:
https://developer.apple.com/videos/play/wwdc2015/407/
Apple sigue cambiando de opinión sobre el tema, lo que nos dice que no hay una única respuesta correcta a esta pregunta. Para demostrar que incluso los ingenieros de Apple están divididos en este tema, eche un vistazo al código de muestra más reciente de Apple, y verá que algunas personas usan débil y otras no.
Este ejemplo de Apple Pay usa débil: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DontLinkElección
Como lo hace este ejemplo de imagen en imagen: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFlayer_Pidlive_Peller_publicidad_publicidad_publicacion_de_publicacion_de_publicacion_de_publicacion_de_publicacion
Al igual que el ejemplo de Lister: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57
Al igual que el ejemplo de ubicación central: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElección
Al igual que la vista ejemplo vista previa controlador: https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc/uid/TP40016546-Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift-DontLinkElementID_5
Como lo hace el ejemplo de HomeKit: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalog_Hit_Aletal_servicio_Control_Actualizador_de_Archivo_De_At_sitio_de_Archivo_de_Archivo_de_Archivo_de_Archivo_de_Archivo_de_Archivado
Todos están completamente actualizados para iOS 9, y todos usan salidas débiles. De esto aprendemos que A. El problema no es tan simple como algunas personas piensan que es. B. Apple ha cambiado de opinión repetidamente, y C. Puedes usar lo que te haga feliz :)
Un agradecimiento especial a Paul Hudson (autor de www.hackingwithsift.com) que me dio la aclaración y referencias para esta respuesta.
¡Espero que esto aclare el tema un poco mejor!
Cuídate.
fuente
Desde WWDC 2015 hay una sesión sobre Implementación de diseños de interfaz de usuario en Interface Builder . Alrededor de la marca de 32 minutos, dice que siempre quieres
@IBOutletfortalecerte .fuente
Tenga en cuenta,
IBOutletCollectiondebería ser@property (strong, nonatomic).fuente
copycomo es unNSArray?Parece que algo ha cambiado con los años y ahora Apple recomienda usar fuerte en general. La evidencia en su sesión de WWDC está en la sesión 407: Implementación de diseños de interfaz de usuario en Interface Builder y comienza a las 32:30. Mi nota de lo que dice es (casi, si no exactamente, citandolo):
las conexiones de salida en general deberían ser fuertes, especialmente si conectamos una subvista o restricción que no siempre es retenida por la jerarquía de vistas
es posible que se necesite una conexión de salida débil al crear vistas personalizadas que tengan alguna referencia a algo que se respalde en la jerarquía de vistas y, en general, no se recomienda
En otros barrios, siempre debería ser fuerte siempre que parte de nuestra vista personalizada no cree un ciclo de retención con parte de la vista en la jerarquía de vistas
EDITAR:
Algunos pueden hacer la pregunta. ¿Mantenerlo con una referencia fuerte no crea un ciclo de retención ya que el controlador de vista raíz y la vista propietaria mantienen la referencia? ¿O por qué sucedió ese cambio? Creo que la respuesta es anterior en esta charla cuando describen cómo se crean las puntas a partir de la xib. Hay una punta separada creada para un VC y para la vista. Creo que esta podría ser la razón por la que cambian las recomendaciones. Aún así, sería bueno obtener una explicación más profunda de Apple.
fuente
Creo que la información más importante es: los elementos en xib están automáticamente en subvistas de vista. Subviews es NSArray. NSArray posee sus elementos. etc tienen punteros fuertes en ellos. Entonces, en la mayoría de los casos, no desea crear otro puntero fuerte (IBOutlet)
Y con ARC no necesitas hacer nada en
viewDidUnloadfuente