Estoy desarrollando exclusivamente para iOS 5 usando ARC. En caso IBOutlet
es que UIView
s (y subclases) sea strong
o 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 strong
igual que las propiedades generadas automáticamente que se crean al conectarse directamente al encabezado desde el editor 'Interface Builder', pero ¿por qué? El UIViewController
ya tiene una strong
referencia a su view
que conserva sus subvistas.
IBOutletCollection()
no debe serweak
, de lo contrario vuelve comonil
.strong
Respuestas:
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
weak
propiedades en subvistas, desde iOS 6 parece estar bien usarstrong
(el calificador de propiedad predeterminado) en su lugar. Eso es causado por el cambio enUIViewController
que las vistas ya no se descargan.Dicho esto, estoy dividido entre usar
y
en iOS 6 y posterior:
El uso
weak
indica claramente que el controlador no desea la propiedad del botón.Pero omitir
weak
no 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 aweak
IBOutlet
s.No usar
weak
puede 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
nil
manual.weak
es un poco más barato en ARM64: Dweak
propiedades o las__weak
variables de instancia son el camino a seguir. Solo quería señalar que hay menos posibilidades de error aquí. En cuanto aweak
ser más barato en arm64, ni siquiera he visto un problema de rendimiento en la vida real conweak
IBOutlet
s en armv7. :)strong
tiene sentido también.strong
solo 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 referenciaviewDidUnload
para 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
weak
no es necesario incluir las propiedadesviewDidUnload
. Pero, ¿por qué la plantilla de Apple para crear puntos de venta incluye un[self setMySubview:nil]
?IBOutlet
debe 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
strong
Si 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
@IBOutlet
fortalecerte .fuente
Tenga en cuenta,
IBOutletCollection
debería ser@property (strong, nonatomic)
.fuente
copy
como 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
viewDidUnload
fuente