Diferencias entre fuertes y débiles en Objective-C

308

Soy nuevo en Obj-C, así que mi primera pregunta es:

¿Cuáles son las diferencias entre strongy weaken las @propertydeclaraciones de punteros a objetos?

Además, ¿qué nonatomicsignifica?

Mark Pegasov
fuente
19
en realidad esta es una buena pregunta, a veces, olvidamos cómo funciona el concepto básico de preferencias fuertes / débiles y atómicas / no atómicas ... :) Gracias por recordárnoslo ...
andikurnia
10
@JackyBoy Lo curioso es que la búsqueda simple propuesta en Google me llevó aquí jajaja. #circularreference
Jason Renaldo
10
Tiendo a no confiar en muchas de las respuestas en google, pero siempre me refiero a SO para obtener respuestas inteligentes
JeffK

Respuestas:

642

Una referencia fuerte (que usará en la mayoría de los casos) significa que desea "poseer" el objeto al que hace referencia con esta propiedad / variable. El compilador se encargará de que cualquier objeto que asigne a esta propiedad no se destruya siempre que lo señale con una referencia fuerte. Solo una vez que establezca la propiedad nil, el objeto se destruirá (a menos que uno o más de los otros objetos también tengan una fuerte referencia a él).

Por el contrario, con una referencia débil significa que no desea tener control sobre la vida útil del objeto. El objeto al que hace referencia débilmente solo vive porque al menos otro objeto tiene una fuerte referencia a él. Una vez que ya no sea así, el objeto se destruye y su propiedad débil se configurará automáticamente nil. Los casos de uso más frecuentes de referencias débiles en iOS son:

  1. delegar propiedades, a las que a menudo se hace referencia débilmente para evitar retener ciclos, y

  2. subvistas / controles de la vista principal de un controlador de vista porque esas vistas ya están fuertemente controladas por la vista principal.

atómico versus no atómico se refiere a la seguridad de subprocesos de los métodos getter y setter que el compilador sintetiza para la propiedad. atomic (el valor predeterminado) le dice al compilador que haga que los métodos de acceso sean seguros para subprocesos (agregando un bloqueo antes de acceder a un ivar) y nonatomic hace lo contrario. La ventaja de no atómico es un rendimiento ligeramente superior. En iOS, Apple usa no atómico para casi todas sus propiedades, por lo que el consejo general es que usted haga lo mismo.

Ole Begemann
fuente
28
@Bourne: Eso depende de lo que quieras decir con seguridad de hilo. atomicgarantiza que la propiedad se pueda leer y escribir de forma segura desde varios hilos al mismo tiempo. Eso no significa que un objeto cuyas propiedades son todas atomicsea ​​automáticamente seguro para subprocesos.
Ole Begemann
3
Grandes detalles Creo que realmente no lo entendí hasta ahora. Gracias.
ahmedalkaff
1
Según la documentación de Apple, atómica y no atómica deben ser sinónimo de seguridad de subprocesos. developer.apple.com/library/ios/documentation/cocoa/conceptual/…
Murtaza Khursheed Hussain
55
"Nota: la atomicidad de la propiedad no es sinónimo de la seguridad del hilo de un objeto". developer.apple.com/library/ios/documentation/cocoa/conceptual/…
GS
¿Por qué no eliminamos la instancia cuando no queremos? ¿Por qué no podemos simplemente sacar el aire del globo o destruirlo cuando no queremos, por qué tenemos que preocuparnos por las condiciones? Solo necesitamos datos.
Ashish Pisey
707

Puede ser útil pensar en referencias fuertes y débiles en términos de globos.

Un globo no saldrá volando mientras al menos una persona se aferre a una cuerda unida a él. El número de personas que tienen cadenas es el recuento de retención. Cuando nadie se aferra a una cuerda, el globo se irá volando (dealloc). Muchas personas pueden tener cadenas para ese mismo globo. Puede obtener / establecer propiedades y métodos de llamada en el objeto referenciado con referencias fuertes y débiles.

Una referencia fuerte es como sujetar una cuerda a ese globo. Mientras sostengas una cuerda atada al globo, no se irá volando.

Una referencia débil es como mirar el globo. Puede verlo, acceder a sus propiedades, llamar a sus métodos, pero no tiene una cadena para ese globo. Si todos los que se aferran a la cuerda se sueltan, el globo se va volando y ya no puede acceder a él.

MJN
fuente
68
+2 (si solo pudiera). En serio, ¡explicación realmente creativa!
Con Antonakos
25
Después de 1 año y medio de desarrollo de iOS, creo que sólo ahora claramente entendido lo strongy weaksignifican realmente.
Isuru
17
@ X.Li El ciclo de retención es como si tuvieras 2 cuerdas en el globo, una de ellas es tuya (por lo que eres dueño de este globo), la otra es propiedad del globo (así que este globo te pertenece). Como solo tienes acceso a tu cuerda, ¿cómo dejas ir el globo si el globo no quiere ir? Por lo tanto, es mejor que tengas el balón (fuerte) mientras que el balón no te pertenece (débil) Cuando quieras dejarlo ir, solo corta la cuerda :)
snakeninny
55
Lea su perfil, es un instructor de iOS. ¡Explicación muy creativa!
Me quito el
3
Atómico versus no atómico, creo que se puede describir como un baño público con múltiples puertas, con un baño en el centro. Una vez que alguien entra al baño a través de una puerta, podría cerrar todas las demás puertas en el baño si no quiere experimentar un momento de incomodidad. Jajaja Gracias por leer esta analogía sin sentido.
Chen Li Yong
24

fuerte : le asigna el valor entrante, retendrá el valor entrante y liberará el valor existente de la variable de instancia

débil : le asignará el valor entrante sin retenerlo.

Entonces, la diferencia básica es la retención de la nueva variable. En general, desea retenerlo, pero hay situaciones en las que no desea tenerlo; de lo contrario, obtendrá un ciclo de retención y no podrá liberar la memoria de los objetos. P.ej. obj1 retiene obj2 y obj2 retiene obj1. Para resolver este tipo de situación, utiliza referencias débiles.

Pfitz
fuente
12

Una respuesta ficticia: -

Creo que la explicación se da en la respuesta anterior, así que solo voy a decir dónde usar STRONGy dónde usar WEAK:

Uso de Weak: - 1. Delegados 2. Puntos de venta 3. Subvistas 4. Controles, etc.

Uso de Strong: - Restante en todas partes que no está incluido en WEAK.

Shubham Mishra
fuente
2
Y qué contiene, etc.: P
Rajneesh071
3
webView, mapView, etc.
shubham mishra
44
en realidad, la mayor parte de la subvista que arrastramos y
soltamos
8

fuertes y débiles , estas palabras clave giran en torno a la propiedad de objetos en Objective-C

¿Qué es la propiedad del objeto?

Las variables de puntero implican la propiedad de los objetos a los que apuntan.

  • Cuando un método (o función) tiene una variable local que apunta a un objeto, se dice que esa variable posee el objeto al que apunta.
  • Cuando un objeto tiene una variable de instancia que apunta a otro objeto, se dice que el objeto con el puntero posee el objeto al que apunta.

Cada vez que una variable de puntero apunta a un objeto, ese objeto tiene un propietario y permanecerá vivo. Esto se conoce como un fuerte referencia .

Una variable opcionalmente no puede tomar posesión de un objeto al que apunta. Una variable que no toma posesión de un objeto se conoce como débil referencia .

Eche un vistazo a una explicación detallada aquí Desmitificando @property y atributos

Vinay Jain
fuente
6

Aquí, la documentación de Apple ha explicado la diferencia entre propiedad débil y fuerte utilizando varios ejemplos:

https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3

Aquí, en este blog, el autor ha recopilado todas las propiedades en el mismo lugar. Ayudará a comparar las características de las propiedades:

http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html

subhash kumar singh
fuente
6

fuerte es el valor predeterminado. Un objeto permanece "vivo" mientras tenga un puntero fuerte.

débil especifica una referencia que no mantiene vivo el objeto referenciado. Una referencia débil se establece en nula cuando no hay referencias fuertes al objeto.

Ankit Vyas
fuente
2

Para entender la referencia fuerte y débil, considere el siguiente ejemplo, suponga que tenemos un método llamado displayLocalVariable.

 -(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
  }

En el método anterior, el alcance de la variable myView se limita al método displayLocalVariable, una vez que el método termina, la variable myView que contiene el objeto UIView se desasignará de la memoria.

Ahora, ¿qué pasa si queremos mantener la variable myView durante todo el ciclo de vida de nuestro controlador de vista? Para esto, podemos crear la propiedad nombrada como usernameView que tendrá una fuerte referencia a la variable myView (ver @property(nonatomic,strong) UIView* usernameView;y self.usernameView = myView;en el código a continuación), como a continuación,

@interface LoginViewController ()

@property(nonatomic,strong) UIView* usernameView;
@property(nonatomic,weak) UIView* dummyNameView;

- (void)displayLocalVariable;

@end

@implementation LoginViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

}

-(void)viewWillAppear:(BOOL)animated
{
     [self displayLocalVariable];
}

- (void)displayLocalVariable
{
   UIView* myView = [[UIView alloc] init];
   NSLog(@"myView tag is = %ld", myView.tag);
   self.usernameView = myView;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


@end

Ahora, en el código anterior, puede ver que myView se ha asignado a self.usernameView y self.usernameView está teniendo una fuerte referencia (como declaramos en la interfaz usando @property) a myView. Por lo tanto, myView no se desasignará de la memoria hasta que self.usernameView esté vivo.

  • Referencia débil

Ahora considere asignar myName a dummyNameView, que es una referencia débil, a self.dummyNameView = myView;diferencia de la referencia fuerte, débil mantendrá myView solo hasta que haya una referencia fuerte a myView. Consulte el siguiente código para comprender la referencia débil.

-(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
     self.dummyNameView = myView;
  }

En el código anterior hay una referencia débil a myView (es decir, self.dummyNameView tiene una referencia débil a myView) pero no hay una referencia fuerte a myView, por lo tanto self.dummyNameView no podrá mantener el valor myView.

Ahora nuevamente considere el siguiente código,

-(void)displayLocalVariable
      {
         UIView* myView = [[UIView alloc] init];
         NSLog(@"myView tag is = %ld", myView.tag);
         self.usernameView = myView;
         self.dummyNameView = myView;
      } 

En el código anterior, self.usernameView tiene una referencia fuerte a myView, por lo tanto, self.dummyNameView ahora tendrá un valor de myView incluso después de que termine el método, ya que myView tiene una referencia Strong asociada.

Ahora, siempre que hagamos una referencia fuerte a una variable, su recuento de retención aumentará en uno y la variable no se desasignará hasta que su recuento de retención llegue a 0.

Espero que esto ayude.

Mahadev Mandale
fuente
2019-07-25 12: 33: 15.479002 + 0530 StrongAndWeak [6329: 245483] Mi nombre es = ABC 2019-07-25 12: 33: 15.479226 + 0530 StrongAndWeak [6329: 245483] Mi nombre es para strong = ABC 2019- 07-25 12: 33: 15.479418 + 0530 StrongAndWeak [6329: 245483] Mi nombre es débil = ABC en esto usted dijo que la propiedad débil no tiene valor de mi nombre. Pero estoy obteniendo el valor de mi nombre como ABC para ambas referencias. ..? puede dar una respuesta más clara .... Gracias de
antemano
@Raviteja_DevObal ARC no promete hacerlo de inmediato (es decir, desasignar la cadena @ "ABC"), pero seguramente desasignará más adelante ...
Mahadev Mandale
@Raviteja_DevObal Como se explica aquí, las cadenas son un mal ejemplo para esto. He actualizado mi respuesta con el objeto UIView, espero que ayude.
Mahadev Mandale
1

Fuerte : Básicamente utilizado con las propiedades que usamos para obtener o enviar datos desde / hacia otras clases. Débil : por lo general, todas las salidas, las conexiones son de tipo Débil desde la interfaz.

No atómico : este tipo de propiedades se utilizan en condiciones en las que no queremos compartir nuestra salida u objeto en diferentes subprocesos simultáneos. En otras palabras, la instancia no atómica hace que nuestras propiedades se ocupen de un hilo a la vez. Espero que sea útil para usted.

Joga Singh
fuente