Objective-C ARC: fuerte versus retener y débil versus asignar

Resuelto Jakub Arnold asked hace 54 años • 8 respuestas

Hay dos nuevos atributos de administración de memoria para las propiedades introducidas por ARC strongy weak.

Aparte de copyque obviamente es algo completamente diferente, ¿ hay alguna diferencia entre strongvs retainy weakvs assign?

Según tengo entendido, la única diferencia aquí es que weakse asignará nilal puntero, mientras que assignno, lo que significa que el programa fallará cuando envíe un mensaje al puntero una vez que se haya liberado. Pero si uso weak, esto nunca sucederá, porque enviar un mensaje a nilno hará nada.

No conozco ninguna diferencia entre strongy retain.

¿Hay alguna razón por la que debería usar assigny retainen proyectos nuevos, o este tipo de uso está en desuso?

Jakub Arnold avatar Jan 01 '70 08:01 Jakub Arnold
Aceptado

Después de leer tantos artículos, publicaciones de Stackoverflow y aplicaciones de demostración para verificar los atributos de propiedades variables, decidí reunir toda la información de los atributos:

  1. atómico //predeterminado
  2. no atómico
  3. fuerte=retener //predeterminado
  4. débil
  5. retener
  6. asignar //predeterminado
  7. inseguro_no retenido
  8. Copiar
  9. solo lectura
  10. leer escribir //predeterminado

A continuación se muestra 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 mejores respuestas aquí!!

Atributos de propiedad variable o modificadores en iOS

1.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 sólo si necesita retener el objeto.
  • De forma predeterminada, todas las variables de instancia y las variables locales son indicadores sólidos.
  • Generalmente usamos strong para UIViewControllers (padres de elementos de 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 cuando haya terminado con él. Usar la palabra clave fuerte significa que usted es dueño del objeto.

Ejemplo:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

2.débil -

  • dice "mantén esto mientras alguien más lo indique fuertemente"
  • lo mismo que asignar, no retener ni liberar
  • Una referencia "débil" es una referencia que no se conserva.
  • Generalmente usamos débil para IBOutlets (Niños de UIViewController). Esto funciona porque el objeto secundario solo necesita existir mientras exista el objeto principal.
  • una referencia débil es una referencia que no protege el objeto al que se hace referencia de la recolección por parte de un recolector de basura.
  • Débil es esencialmente asignar, una propiedad no retenida. Excepto cuando se desasigna el objeto, el puntero débil se establece automáticamente en cero

Ejemplo :

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

@synthesize myButton;

Explicación fuerte y débil, gracias a BJ Homer :

Imagine que nuestro objeto es un perro y que el perro quiere huir (ser desasignado).

Los consejos fuertes son como una correa para el perro. Mientras tengas la correa atada al perro, este no se escapará. Si cinco personas atan su correa a un perro (cinco fuertes indicaciones para un objeto), entonces el perro no huirá hasta que se suelten las cinco correas.

Los punteros débiles, por otro lado, son como niños pequeños que señalan al perro y dicen "¡Mira! ¡Un perro!" Mientras el perro todavía esté atado, los niños pequeños aún podrán verlo y seguirán señalándolo. Sin embargo, tan pronto como se sueltan 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 será desasignado y todos los punteros débiles se pondrán a cero.

¿Cuándo usamos débil?

El único momento en el que querrías usar débil es si quisieras evitar los ciclos de retención (por ejemplo, el padre retiene al niño y el niño retiene al padre para que ninguno de los dos sea liberado).

3.retener = fuerte

  • se retiene, el valor anterior se libera y se asigna retener especifica que se debe enviar el nuevo valor
  • retener en la asignación y el valor anterior enviado -liberar
  • retener es lo mismo que fuerte.
  • Apple dice que si escribes retener, se convertirá automáticamente/funcionará solo como fuerte.
  • métodos como "alloc" incluyen un "retain" implícito

Ejemplo:

@property (nonatomic, retain) NSString *name;

@synthesize name;

4.asignar

  • asignar es el valor predeterminado y simplemente realiza una asignación de variable
  • asignar es un atributo de propiedad que le dice al compilador cómo sintetizar la implementación del definidor de la propiedad.
  • Usaría asignar para propiedades primitivas de C y débil para referencias débiles a objetos Objective-C.

Ejemplo:

@property (nonatomic, assign) NSString *address;

@synthesize address;
swiftBoy avatar Mar 21 '2013 07:03 swiftBoy

De las notas de la versión de transición a ARC (el ejemplo en la sección sobre atributos de propiedad).

// The following declaration is a synonym for: @property(retain) MyClass *myObject;

@property(strong) MyClass *myObject;

Es stronglo mismo que retainen una declaración de propiedad.

Para proyectos ARC usaría strongen lugar de retain, lo usaría assignpara propiedades primitivas de C y weakpara referencias débiles a objetos Objective-C.

JeremyP avatar Jan 19 '2012 14:01 JeremyP

no atómico/atómico

  • No atómico es mucho más rápido que atómico.
  • Utilice siempre no atómico a menos que tenga un requisito muy específico para atómico, lo cual debería ser poco común (atómico no garantiza la seguridad de los subprocesos; solo detiene el acceso a la propiedad cuando otro subproceso la establece simultáneamente)

fuerte/débil/asignar

  • use fuerte para retener objetos; aunque la palabra clave retener es sinónima, es mejor usar fuerte en su lugar
  • use débil si solo desea un puntero al objeto sin retenerlo - útil para evitar ciclos de retención (es decir, delegados) - automáticamente anulará el puntero cuando se libere el objeto
  • use asignar para primitivas - exactamente igual que débil excepto que no anula el objeto cuando se libera (configurado de forma predeterminada)

(Opcional)

Copiar

  • Úselo para crear una copia superficial del objeto.
  • Es una buena práctica establecer siempre propiedades inmutables para copiar: debido a que las versiones mutables se pueden pasar a propiedades inmutables, la copia garantizará que siempre estará tratando con un objeto inmutable.
  • si se pasa un objeto inmutable, lo retendrá; si se pasa un objeto mutable, lo copiará

solo lectura

  • Úselo para deshabilitar la configuración de la propiedad (evita que el código se compile si hay una infracción)
  • puede cambiar lo que entrega el getter cambiando la variable directamente a través de su variable de instancia o dentro del método getter mismo.
Vadoff avatar Oct 08 '2014 18:10 Vadoff

Hasta donde yo sé, strongy retainson sinónimos, hacen exactamente lo mismo.

Entonces weakes casi como assign, pero se establece automáticamente en nil después de que se desasigna el objeto al que apunta.

Eso significa que puedes simplemente reemplazarlos.

Sin embargo , me he encontrado con un caso especial en el que tuve que usar assign, en lugar de weak. Digamos que tenemos dos propiedades delegateAssigny delegateWeak. En ambos se almacena nuestro delegado, que nos posee al tener la única referencia fuerte. El delegado está desasignando, por lo que -dealloctambién se llama a nuestro método.

// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
    [delegateWeak doSomething];
    [delegateAssign doSomething];
}

El delegado ya se encuentra en el proceso de desasignación, pero aún no se ha desasignado por completo. ¡El problema es que weaklas referencias a él ya están anuladas! La propiedad delegateWeakcontiene cero, pero delegateAssigncontiene un objeto válido (con todas las propiedades ya publicadas y anuladas, pero aún válidas).

// Our delegate is deallocating and there is no other strong ref.
- (void)dealloc {
    [delegateWeak doSomething]; // Does nothing, already nil.
    [delegateAssign doSomething]; // Successful call.
}

Es un caso bastante especial, pero nos revela cómo weakfuncionan esas variables y cuándo se anulan.

Tricertops avatar Jan 27 '2013 09:01 Tricertops