Atributos de establecimiento de propiedades débiles y fuertes en Objective-C

94

¿Cuál es la diferencia entre los atributos de establecimiento de propiedades débiles y fuertes en Objective-C?

@property(retain, [weak/strong]) __attribute__((NSObject)) CFDictionaryRef myDictionary;

¿Cuál es el impacto y el beneficio?

Escuché que débil no está disponible en iOS 4 y necesitamos usar asignar.

¿Es débil similar a asignar?

kkurni
fuente

Respuestas:

102

Tiene ARC activado o desactivado para un archivo en particular. Si está activado, no puede usar, retain release autoreleaseetc. En su lugar, use strong weakpara propiedades o __strong __weak variables (predeterminado en __strong). Fuerte es el equivalente a retener, sin embargo, ARC gestionará el lanzamiento por usted.

La única vez que querría usar débil es si desea evitar los ciclos de retención (por ejemplo, el padre retiene al hijo y el hijo retiene al padre, por lo que ninguno de los dos se libera).

La parte de 'puenteo gratuito' (pasar de NSa CF) es un poco complicada. Todavía tiene que administrar manualmente CFRelease()y CFRetain()para los objetos CF. Cuando los vuelve a convertir en objetos NS, debe informar al compilador sobre el recuento de retención para que sepa lo que ha hecho.

Todo está aquí .

Robert
fuente
119

Aquí hay información sobre lo que sé sobre propiedades variables.

  1. atómico // predeterminado
  2. no atómico
  3. fuerte = retener // predeterminado
  4. débiles
  5. conservar
  6. asignar // predeterminado
  7. unsafe_unretained
  8. Copiar
  9. solo lectura
  10. readwrite // predeterminado

así que a continuación está el enlace del artículo detallado donde puede encontrar todos los atributos mencionados anteriormente, que definitivamente lo ayudarán. ¡¡Muchas gracias a todas las personas que dan las mejores respuestas aquí !!

Atributos de propiedades variables o modificadores en iOS

01. fuerte (iOS4 = retener) - dice "mantén esto en el montón hasta que ya no lo señale" - en otras palabras "Soy el propietario, no puedes desasignar esto antes de apuntar bien con lo mismo que retener "- Utilice fuerte solo si necesita retener el objeto. - De forma predeterminada, todas las variables de instancia y las variables locales son punteros fuertes. - Generalmente usamos strong para UIViewControllers (los padres del elemento UI) - strong se usa con ARC y básicamente te ayuda, al no tener que preocuparte por el recuento de retención de un objeto. ARC lo libera automáticamente para usted cuando haya terminado con él. Usar la palabra clave fuerte significa que usted es el propietario del objeto.

Ejemplo:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02. débil (iOS4 = unsafe_unretained) - dice "mantén esto mientras alguien más lo señale fuertemente" - lo mismo que asignar, no retener o liberar - Una referencia "débil" es una referencia que no retienes. - Generalmente usamos débil para IBOutlets (Childs de UIViewController). Esto funciona porque el objeto hijo solo necesita existir mientras el objeto padre lo haga. - una referencia débil es una referencia que no protege el objeto referenciado de la recolección por parte de un recolector de basura. - Débil es esencialmente asignar, una propiedad no retenida. Excepto cuando el objeto se desasigna, el puntero débil se establece automáticamente en cero

Ejemplo:

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

@synthesize myButton;

Explique : Gracias a BJ Homer

Imagine que nuestro objeto es un perro y que el perro quiere huir (ser desasignado). Los punteros fuertes son como una correa para el perro. Mientras tenga la correa atada al perro, el perro no huirá. Si cinco personas atan su correa a un perro, (cinco punteros fuertes a un objeto), entonces el perro no se escapará hasta que las cinco correas estén sueltas. Los punteros débiles, por otro lado, son como niños pequeños señalando al perro y diciendo "¡Mira! ¡Un perro!" Mientras el perro siga con la correa, los niños pequeños aún pueden ver al perro y aún lo señalarán. Sin embargo, tan pronto como se quitan todas las correas, el perro huye sin importar cuántos niños pequeños lo señalen. Tan pronto como el último puntero fuerte (correa) ya no apunte a un objeto, el objeto se desasignará y todos los punteros débiles se pondrán a cero. ¿Cuándo usamos débil? La única vez que querría usar débil es si desea evitar los ciclos de retención (por ejemplo, el padre retiene al hijo y el hijo retiene al padre, por lo que ninguno de los dos se libera).

SwiftBoy
fuente
1
En la lista inicial, no estoy muy seguro de lo que quiere decir con "predeterminado". Tiene ambos strong=retainy assignetiquetados como predeterminados, pero no puede ser ambos.
Slipp D. Thompson
27
Disfruté del perro en la comparación de la correa. Lo explica bastante bien.
Jarrett Barnett
1
Buena explicación, aunque iOS no utiliza la recolección de basura. ARC! = Recolección de basura (!), Estas son tecnologías diferentes.
1
débil e inseguro_no retenido son diferentes (el primero usa referencias débiles de reducción a cero, mientras que el último hace sentadilla)
wcochran
1
Solo estoy aprendiendo iOS, pero parece que has perdido el weaky strongen tus ejemplos. ¿No tendría más sentido que un padre tenga strongreferencias a sus hijos (como la myButtonpropiedad de la UIViewControllerclase que ha demostrado ser weak) y que los hijos mantengan weakreferencias a su padre (como la viewControllerpropiedad de una clase secundaria que usted ' en su lugar, lo configuró en strong). Por ejemplo, al leer Matt Neuburg iOS 7 Programming Fundamentals, muestra que una clase que declara a su delegado como una propiedad la mantendrá `débil, eso parece justo.
Bogdan Alexandru
2

Para mencionar las partes de los documentos a los que hace referencia Robert que responden sus dos últimas preguntas explícitamente:

// The following declaration is similar to "@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;

Esto se conoce como referencia débil de reducción a cero. Puede crear referencias débiles que no pongan a cero las referencias débiles utilizando __unsafe_unretained, pero como su nombre lo indica, esto generalmente no se recomienda.

También en los documentos:

Weak references are not supported in Mac OS X v10.6 and iOS 4.
rimsky
fuente
1
Sí, esto es correcto, __unsafe_unretainedes la versión ARC de assign.
Robert
2

El uso cristalino de la propiedad DÉBIL es el siguiente:

Any control whose properties we need to change(eg:text of a label) is declared weak and as below:

@property(nonatomic,weak) IBOutlet Type *name;
Eg: @property(nonatomic,weak) IBOutlet UILabel *myLabel;
Alen Alexander
fuente
1
Usando débil en mis propiedades, recibo una advertencia que dice: "El receptor débil puede estar configurado impredeciblemente a cero". He visto algunas otras publicaciones que para evitar esta advertencia, debes crear una referencia fuerte local. Y si esto es cierto, ¿de qué sirve debilitar una propiedad, si al final tengo que crear una referencia fuerte?
arh
0

tomemos un ejemplo para elaborar más (las respuestas anteriores ya son geniales), que este ejemplo ayude un poco más

tengamos dos clases A y B

//A.h

#import <Foundation/Foundation.h>
#import "B.h"

@interface A : NSObject

@property (nonatomic, strong) B *objB;

@end

@implementation A
//

@end

//B.h

    #import <Foundation/Foundation.h>
    #import "A.h"


    @interface B : NSObject

    @property strong text(nonatomic, strong) A *objA;

    @end

    @implementation B
    //

    @end

    and in main

    #import "B.h"
    #import "A.h"

    {
    A *obja =[[A alloc]init];
    B *objb =[[B alloc]init];
    A.objB=objb;
    B.objA=obja;
   }

el código anterior generará un ciclo de retención porque ambos son del tipo fuerte a --------> b ---------> a

por lo que para evitarlo, debe usar la propiedad week de uno de ellos para que se refiera semanalmente al objeto y no aumente el recuento de referencias.

Anurag Bhakuni
fuente