Estoy desarrollando en exclusiva para iOS 5 usando el ARCO. Debe IBOutlets a UIViews (y subclases) ser strong o weak?

Los siguientes:

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

Sería deshacerse de todo esto:

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

Hay algún problema al hacer esto? Las plantillas están utilizando strong como son los generados automáticamente las propiedades creadas cuando se conecta directamente a la cabecera de la ‘Interfaz’ editor, pero ¿por qué? El UIViewController ya tiene un strong referencia a su view que conserva su subvistas.

  • Como una nota, IBOutletCollection() no debe ser weak, en caso contrario devuelve como nil.
  • Xcode 8.2.1 utiliza débil a la hora de crear IBOutlets a través de la interface builder. Sin embargo muchas de las respuestas aquí, en LO aconseja el uso fuerte.
  • Acabo de probar con xcode 8.3.2 arrastrando desde el guión a swift archivo y el valor predeterminado es strong
InformationsquelleAutor hypercrypt | 2011-10-06

11 Comentarios

  1. 229

    La actual práctica recomendada de Apple es para IBOutlets a ser fuerte menos débil es específicamente necesario para evitar retener ciclo. Como Johannes se mencionó anteriormente, este fue comentado en la «Implementación de Diseños de interfaces de usuario en el Interface Builder» período de sesiones de la WWDC 2015, donde un Ingeniero de Apple dijo:

    Y la última opción que yo quiero señalar es que el tipo de almacenamiento, que puede
    ser fuerte o débil. En general, usted debe hacer su toma de corriente
    fuerte, especialmente si se conecta a una toma de corriente para una subvista o a
    una restricción que no siempre va a ser retenido por la vista
    jerarquía. La única vez que usted realmente necesita para hacer una toma de corriente débil es si
    tiene una vista personalizada que hace referencia a algo de la espalda hasta la vista
    jerarquía y, en general, no se recomienda.

    Le pregunté acerca de esto en Twitter a un ingeniero en el IB equipo y confirmó que fuerte debe ser el predeterminado y que el developer docs están siendo actualizados.

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

    Debe IBOutlets ser fuerte o débil bajo el ARCO?
    Debe IBOutlets ser fuerte o débil bajo el ARCO?

    • Es esto verdad o es la respuesta con 300+ upvotes el correcto? Me di cuenta de que InterfaceBuilder por defecto usa débil cuando la tecla Ctrl y arrastre desde el guión a la .h
    • El uno con más de 400 votos es correcta, pero obsoleto. Desde iOS 6 viewDidUnload no consigue llamado, por lo que no hay beneficios por haber débil de comunicación.
    • hay beneficios. Primero y ante todo, no debe mantener una fuerte referencia a algo en lo que no cree. Segundo, la ganancia de rendimiento es insignificante. No violar las mejores prácticas de programación, simplemente porque un tipo, incluso un chico, dijo que esta es de 10 microsegundos más rápido. Código clara intención, no intentar jugar a la optimización del compilador. Sólo el código para el rendimiento cuando se ha medido en un caso específico de un problema.
    • Permítanme discrepar con usted. ‘La celebración de una fuerte referencia a algo en lo que no cree’ que sucede todo el tiempo en Objective-C. es por ello Que hay una referencia conteo, en lugar de un solo dueño. ¿Tienen alguna referencia a esta recomendación? Podría pls lista de los otros beneficios de la debilidad de los establecimientos?
    • Aquí está la WWDC de vídeo se menciona en la respuesta developer.apple.com/videos/play/wwdc2015/407/?time=1946
    • «¿Es esto realmente cierto o es la respuesta con [más] upvotes el correcto?», no es realmente una pregunta válida, cuando esta respuesta se cita un ingeniero de Apple como de su fuente. Usted puede considerar lo que Apple dice acerca de Apple el uso de la API de ser la correcta, por definición.
    • Casi 3 años después de Apple docs todavía del estado que deben ser débil a pesar de que «a excepción de los de Propietario del Archivo a objetos de nivel superior». Así que tenemos confianza en el docs o el ingeniero?
    • docs!
    • Esta respuesta sólo dice «haz esto» y no explica nada. Si necesito referencias débiles a veces, y en otras ocasiones no importa, ¿por qué yo nunca la uso fuertes referencias? No me importa que publica esta información, no tiene que ser explicado, de lo contrario es sólo la opinión de alguien.
    • Es curioso que la tecla Ctrl y arrastrar para .h archivos aún crea débil (como de XCode 10) si esto no es recomendable. No tengo problemas con esto, sin embargo. Todo funciona. Es bastante confuso.
    • No estoy de acuerdo con eso. El IBOutlets debe ser declarada débil. La creación de fuertes referencias no permitir puntos de vista para desasignar. Es una buena práctica, pero puede ser una preferencia personal, para aquellos que saben lo que están haciendo. Por ejemplo crear una fuerte referencia a un anidada subvista en el controlador y la supresión de sus padres vista no desasignar la memoria, debido a su fuerte. Mejor aún, haz salidas opcionales en lugar de implícitamente envueltos para evitar los accidentes.

  2. 448

    ADVERTENCIA, ANTICUADO RESPUESTA: esta respuesta no es hasta la fecha como por la WWDC 2015, para la respuesta correcta de referirse a la aceptado respuesta (Daniel Hall) anterior. Esta respuesta va a permanecer para grabar.


    Resumen de la desarrollador de la biblioteca:

    Desde una perspectiva práctica, en iOS y OS X salidas deben ser definida como declaró propiedades. Los tomacorrientes deben ser, en general débiles, excepto las de Propietario del Archivo a objetos de nivel superior en un archivo nib (o, en iOS, un storyboard de la escena), que debe ser fuerte. Puntos de venta, que se crea por lo tanto, suelen ser débiles por defecto, porque:

    • De comunicación que usted cree, por ejemplo, subvistas de un controlador de vista de la vista o en una ventana del controlador de la ventana, son arbitrarias las referencias entre objetos que no implica la tenencia.

    • Las fuertes salidas son con frecuencia especificada por el marco de las clases (por ejemplo, UIViewController vista de la toma de corriente, o NSWindowController la ventana de salida).

      @property (weak) IBOutlet MyView *viewContainerSubview;
      @property (strong) IBOutlet MyOtherClass *topLevelObject;
    • ¿Cómo conseguir el «desarrollador» de la biblioteca de enlace para saltar a la parte específica de la manzana doc página? Siempre que enlace a la manzana docs se vincula siempre a la parte superior de la página (incluso si el contenido es de interés la mitad de la página). Gracias.
    • He copiado el enlace desde el panel de navegación de la izquierda. 😀
    • ¿Qué significa «excepto las de Propietario del Archivo a objetos de nivel superior en un archivo nib (o, en iOS, un storyboard de la escena)» significa?
    • significa que los objetos en la PUNTA que están a nivel de la raíz, es decir, decir que se crea una instancia de otro punto de vista en que no es directamente una subvista de la vista principal, entonces se necesita tener una referencia fuerte.
    • Sí, pero usted no respondió directamente a la pregunta.
    • Si ese es el caso, entonces ¿por qué es cuando se elige «débil» de la arrastrar-y-gota Referencia a puntos de venta, Xcode rellena automáticamente como «unsafe_unretained»? Cual es la correcta?
    • De nivel superior significa que cuando usted mira la punta, el objeto aparece en la lista de la izquierda. Casi todas las puntas tienen un UIView en ellos – este podría ser el único objeto de nivel superior. Si se añaden otros elementos, y se muestran en la lista, son «de nivel superior de los objetos»
    • Así que todavía tenemos que hacer topLevelObject=nil en viewDidUnload? De lo contrario, ninguna de las subclases se cancela la asignación, a continuación, dado que topLevelObject todavía tienen referencias a todos ellos.
    • es lo que se va a producir si el proyecto se dirige a una versión de iOS que es mayor que 5, pero sigue siendo compatible con ARC. Si se dirige a sólo 5 o hacia arriba, voy a dar weak lugar.
    • Quiero saber la respuesta a su pregunta demasiado. Debemos establecer la fuerte topLevelObject a nil en viewDidUnload?
    • Es allí cualquier mundo real de los casos donde el uso de fuertes/retenidos para su IBOutlet podría causar el problema? O es sólo un redundantes retener, lo que significa estilo de codificación malo pero no afecta su código?
    • si establece el IBOutlet a ser fuerte(mismo como a conservar), entonces sus puntos de venta tendrá un segundo propietario (el viewcontroller) aparte de la opinión de que la conservaron ya. Así que usted tiene que liberar la memoria utilizada por la que toma en viewcontroller del viewDidUnload.
    • Zhan: true, excepto que viewDidUnload ya no se llama desde iOS 6.
    • hola, sé que hice un buen trabajo explicando esto.. pero me podrían ayudar con esta cuestión? Entiendo diagramas mejor que las palabras –> stackoverflow.com/questions/18969138/…
    • Buen artículo sobre NSHipster sobre el tema: nshipster.com/ibaction-iboutlet-iboutletcollection
    • De nivel superior objeto de la controlador de vista de guión gráfico se almacena en un array: _topLevelObjectsToKeepAliveFromStoryboard, pero no para xib archivo, de modo que la parte superior objetos a nivel de puntos de venta podría ser débil, si usted está utilizando el guión gráfico.
    • Esto parece que no es cierto y los documentos están en proceso de ser actualizado. – twitter.com/_danielhall/status/620716996326350848twitter.com/_danielhall/status/620717252216623104
    • No hay verdad más, debe ser actualizado

  3. 48

    Mientras que la documentación que se recomienda el uso de weak en las propiedades para las subvistas, desde iOS 6 parece estar bien para el uso strong (el valor predeterminado de la propiedad calificador) en su lugar. Que es provocado por el cambio en UIViewController que las vistas no son descargados más.

    • Antes de iOS 6, si mantiene fuertes vínculos con subvistas del controlador de la vista en torno, si el controlador de vista de la vista principal tengo descargado, los que se aferren a la subvistas mientras el controlador de vista es de alrededor de.
    • Desde iOS 6, las vistas no son descargados más, pero cargado de una vez y, a continuación, se pegan alrededor mientras su controlador está ahí. Tan fuertes propiedades no importa. Asimismo, no crear fuertes ciclos de referencia, ya que punto fuerte de referencia gráfico.

    Que dijo, no me puedo decidir entre el uso de

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

    y

    @property (nonatomic) IBOutlet UIButton *button;

    en iOS 6, y después:

    • Utilizando weak claramente indica que el controlador no quiere la titularidad de la marca.

    • Pero omitiendo weak no duele en iOS 6 sin ver la descarga, y es más corto. Puede que algunos señalen que también es más rápido, pero todavía tengo que encontrar una aplicación que es demasiado lento debido a weak IBOutlets.

    • No usar weak puede ser percibido como un error.

    Línea de base: Desde iOS 6, no podemos obtener esta mal, ya que siempre que no utilice la vista de la descarga. Tiempo para la fiesta. 😉

    • Eso es cierto, pero todavía se puede desea descargar la opinión de ti mismo. En cuyo caso tendrías que configurar todos sus puntos de venta nil manualmente.
    • PS: weak es un poco más barato en ARM64 😀
    • Eso es correcto, si se implementa la vista de descarga, weak propiedades o __weak las variables de instancia son el camino a seguir. Yo sólo quería señalar que hay menos posibilidades de error. Como para weak de ser más barato en arm64, aún no he visto una de la vida real problema de rendimiento con weak IBOutlets en armv7. 🙂
    • Ni tengo, y tu punto es muy válida.
    • En ese caso, strong tiene sentido. strong sólo es perjudicial si utiliza la vista de descarga—pero, ¿quién en estos días? 🙂
    • ¿Qué diría usted acerca de esta situación? SO: C Objetivo: GestureRecognizer en ViewController –> retener ciclo
    • Ver mi respuesta allí. No es un problema, ya que el gesto de reconocedores no se mantienen fuertes referencias a los objetivos de/los delegados. 🙂
    • ¿Por qué quieres usar viewUnloading?
    • El primer iPhone es muy limitada RAM. Si recuerdo correctamente, 128 MB, dejando alrededor de 10 MB para la aplicación activa. Tener una pequeña huella de memoria es crucial, por lo tanto no había vista de la descarga. Que ha cambiado ya que ahora tenemos más y más memoria RAM, y Apple optimizado UIViews en iOS 6, así que en la memoria de advertencias, una gran cantidad de memoria que puede ser liberado sin descarga de la vista.

  4. 34

    No veo ningún problema con eso. Pre-ARCO, siempre he hecho mi IBOutlets assign, porque ya están retenidos por sus superviews. Si se hacen weak, usted no debería tener nada en viewDidUnload, como usted señala.

    Una advertencia: Usted puede apoyar a iOS 4.x en un ARCO de proyecto, pero si usted lo hace, usted no puede utilizar weak, de manera que tendría que hacer ellos assign, en cuyo caso usted todavía desea nula la referencia en viewDidUnload para evitar un colgando puntero. He aquí un ejemplo de un colgando puntero error que yo he vivido:

    Un UIViewController tiene un UITextField el código postal. Utiliza CLLocationManager a geocodificación inversa de la ubicación del usuario y establecer el código postal. Aquí está el delegado de devolución de llamada:

    -(void)locationManager:(CLLocationManager *)manager
       didUpdateToLocation:(CLLocation *)newLocation
              fromLocation:(CLLocation *)oldLocation {
        Class geocoderClass = NSClassFromString(@"CLGeocoder");
        if (geocoderClass && IsEmpty(self.zip.text)) {
            id geocoder = [[geocoderClass alloc] init];
            [geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
                if (self.zip && IsEmpty(self.zip.text)) {
                    self.zip.text = [[placemarks objectAtIndex:0] postalCode];
                }
            }];    
        }
        [self.locationManager stopUpdatingLocation];
    }

    He descubierto que si me rechazó este punto de vista, en el momento adecuado y no nil self.zip en viewDidUnload, el delegado de devolución de llamada podría lanzar una mala excepción de acceso en auto.zip.texto.

    • También es mi entendimiento de que weak propiedades no necesita ser el atributo nillable en viewDidUnload. Pero, ¿por qué Apple plantilla para crear salidas incluyen un [self setMySubview:nil]?
    • Es allí cualquier mundo real de los casos donde el uso de fuertes/retenidos para su IBOutlet podría causar el problema? O es sólo un redundantes retener, lo que significa estilo de codificación malo pero no afecta su código?
    • Existe tal cosa como un redundantes retener? Si hay un extra de retener, que hará que no serán tenidos en cuenta adecuadamente, y por lo tanto no se libera tan pronto como podría ser, ya que hay un extra de retener en sus retener a contar.
  5. 21

    IBOutlet debe ser fuerte, por razones de rendimiento. Ver Guión de Referencia, Fuerte IBOutlet, Escena Dock de iOS 9

    Como se explica en este párrafo, los puntos de venta a subvistas de la vista
    controlador de la vista puede ser débil, porque estos ya están subvistas
    propiedad del objeto de nivel superior de la punta de archivo. Sin embargo, cuando una Toma de corriente
    se define como un débil puntero y el puntero se establece, ARCO llama a la
    tiempo de ejecución de la función:

    id objc_storeWeak(id *object, id value);

    Esto se suma el puntero
    (objeto) una tabla con el valor del objeto como una clave. Esta tabla es
    se refiere a como los débiles de la tabla. ARCO utiliza esta tabla para almacenar todos los
    débil punteros de su aplicación. Ahora, cuando el valor del objeto es
    desasignado, el ARCO se repite por la debilidad de la tabla y establecer el débil
    referencia de nada. Alternativamente, el ARCO puede llamar a:

    void objc_destroyWeak(id * object)

    Entonces, el objeto es
    y sin objc_destroyWeak llama de nuevo:

    objc_storeWeak(id *object, nil)

    Este libro de mantenimiento asociados
    con una referencia débil puede tomar de 2 a 3 veces más sobre el lanzamiento de un
    referencia fuerte. Así, una referencia débil introduce una sobrecarga para el
    de la ejecución que se puede evitar simplemente la definición de puntos de venta, fuerte.

    Como de Xcode 7, sugiere strong

    Debe IBOutlets ser fuerte o débil bajo el ARCO?

    Si usted mira la WWDC 2015 sesión 407 La implementación de Diseños de interfaces de usuario en el Interface Builder, sugiere (transcripción de http://asciiwwdc.com/2015/sessions/407)

    Y la última opción que yo quiero señalar es que el tipo de almacenamiento, que puede ser fuerte o débil.

    En general, usted debe hacer su toma de corriente fuerte, especialmente si se conecta a una toma de corriente para un sub vista o a una restricción que no siempre va a ser retenido por el punto de vista de la jerarquía.

    La única vez que usted realmente necesita para hacer una toma de corriente débil es que si usted tiene una vista personalizada que hace referencia a algo a la vista de jerarquía y, en general, no se recomienda.

    Así que voy a elegir fuerte y voy haga clic en conectar, lo que generará mi salida.

    • Gran respuesta que explica la razón real -por qué-
    • Que es bueno y todo, pero he visto las fugas procedentes de gesto reconocedores implementado en el guión gráfico.
    • Todavía se me pone débil como el valor predeterminado (Xcode 8)
    • Yo no puedo entender a esta línea. «La única vez que usted realmente necesita para hacer una toma de corriente débil es que si usted tiene una vista personalizada que hace referencia a algo a la vista de jerarquía y, en general, no se recomienda.» Cualquiera de los ejemplos?
    • He calculado el deinit tiempo que los débiles y los fuertes , y es exactamente el mismo.
    • Pero en swift esto es más el caso. Referencias débiles son más rápidos.

  6. 20

    En el desarrollo de iOS PUNTA de carga es un poco diferente de desarrollo para Mac.

    De Mac en el desarrollo de un IBOutlet es generalmente una referencia débil: si usted tiene una subclase de NSViewController sólo la vista del nivel superior, será retenido y cuando dealloc el controlador de todos sus subvistas y tomas de corriente se libera automáticamente.

    UiViewController uso de la Clave de Codificación de valores para establecer los puntos de venta mediante el uso de potentes referencias. Así que cuando usted dealloc su UIViewController, la parte superior de la vista automáticamente se cancela la asignación, pero también debe cancelar todos sus puntos de venta en el método dealloc.

    En este post desde el Big Nerd Ranch, que cubren este tema y explicar también por qué el uso de una referencia fuerte en IBOutlet no es una buena elección (incluso si es recomendado por Apple en este caso).

    • Se explica como en 2009. Con ARCO, esto ha cambiado significativamente.
    • 🙁 el Big Nerd Ranch enlace está muerto… pero realmente necesito leer. Alguien sabe más detalles acerca de ese puesto, así que la puedo encontrar?
    • no te preocupes, no es gran cosa ya que el enlace era de unos momentos antes de que el ARCO y no es relevante ya.
  7. 16

    Una cosa que quiero destacar aquí, y es que, a pesar de lo que los ingenieros de Apple han indicado en sus propias WWDC 2015 video aquí:

    https://developer.apple.com/videos/play/wwdc2015/407/

    Apple va a cambiar su mente sobre el tema, que nos dice que no hay una sola respuesta correcta a esta pregunta. Para demostrar que incluso los ingenieros de Apple están divididos sobre este tema, echa un vistazo a la más reciente de Apple
    código de ejemplo, y vas a ver que algunas personas débiles, y algunos no.

    Este Apple Pay ejemplo se utiliza débil:
    https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DontLinkElementID_8

    Como lo hace esta imagen-en-imagen de ejemplo:
    https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPPlayer_PlayerViewController_swift-DontLinkElementID_4

    Como lo hace el Lister ejemplo:
    https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57

    Como el Núcleo de la Ubicación de ejemplo:
    https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElementID_6

    Como lo hace la de la vista del controlador de vista previa de ejemplo:
    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 HomeKit ejemplo:
    https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalog_Homes_Action_Sets_ActionSetViewController_swift-DontLinkElementID_23

    Todos aquellos que son completamente actualizado para iOS 9, y todos los débiles puntos de venta. De esto aprendemos que A. La cuestión no es tan simple como algunas personas lo hacen ser. B. Apple ha cambiado su mente varias veces, y C. Usted puede usar lo que te hace feliz 🙂

    Un agradecimiento especial a Pablo Hudson (autor de http://www.hackingwithsift.com) que me dio la aclaración, y referencias para esta respuesta.

    Espero que esto te aclare el tema un poco mejor!

    Cuidar.

    • He estado revisando en este asunto por el momento y no he encontrado ninguna respuesta concreta. Desde el enlace de arriba sugiere que ambas cosas están bien y, en general, seguir con lo que Xcode autosuggests.
  8. 6

    Ser consciente, IBOutletCollection debe ser @property (strong, nonatomic).

    • ¿Por qué no copy como es un NSArray?
  9. 5

    Parece que algo ha cambiado a lo largo de los años y ahora Apple recomienda el uso de fuertes en general. La evidencia en su WWDC sesión en sesión 407 – la Implementación de Diseños de interfaces de usuario en el Interface Builder y comienza a 32:30. Mi nota de lo que dice es (casi, si no exactamente, citando a él):

    • conexiones de salida, en general, debe ser muy importante, especialmente si conectamos una subvista o restricción que no es conservado siempre por el
      vista de la jerarquía de

    • débil conexión de salida puede ser necesaria cuando la creación de vistas personalizadas que haya alguna referencia a algo nuevo en la vista de jerarquía
      y, en general, no se recomienda

    En otros barrios debe ser siempre fuerte ahora mientras algunos de nuestra vista personalizada de no crear una retener ciclo con algunas de las vistas en la vista de jerarquía

    EDICIÓN :

    Algunos pueden hacer la pregunta. No mantener con una fuerte referencia no crear una retener el ciclo de la raíz de controlador de vista y la posesión de la vista se mantiene la referencia a él? O por qué cambió de pasó?
    Creo que la respuesta es anterior en esta charla, cuando se describe la forma de las puntas son creados a partir de la xib. Hay un cuarto de punta creado para un VC y para la vista. Creo que esto podría ser la razón por la que se modifican las recomendaciones. Todavía sería bueno para obtener una explicación más profunda de Apple.

  10. 4

    Creo que la información más importante es:
    Elementos en xib son automáticamente en subvistas de vista. Subvistas es NSArray. NSArray posee elementos. etc tienen una fuerte punteros en ellos. Así, en la mayoría de los casos usted no desea crear otro de los puntos fuertes de puntero (IBOutlet)

    Y con el ARCO que usted no necesita hacer nada en viewDidUnload

Dejar respuesta

Please enter your comment!
Please enter your name here