Hay dos nuevos atributos de administración de memoria para las propiedades introducidas por ARC, strong
y weak
.
Además de la copy
, que obviamente es algo completamente diferente, ¿hay alguna diferencia entre strong
vs retain
y weak
vs assign
?
Según entiendo, la única diferencia aquí es que weak
asignará nil
al puntero, mientras que assign
no lo hará, lo que significa que el progtwig se bloqueará cuando envíe un mensaje al puntero una vez que se haya liberado. Pero si uso weak
, esto no sucederá nunca, porque el mensaje de enviar a nil
no hará nada.
No sé sobre cualquier diferencia entre strong
y retain
.
¿Hay alguna razón por la que debería usar assign
y retain
en proyectos nuevos, o el tipo de obsolescencia es obsoleta?
Desde la Transición a las Notas de versión de ARC (el ejemplo en la sección de atributos de propiedad).
// The following declaration is a synonym for: @property(retain) MyClass *myObject; @property(strong) MyClass *myObject;
Tan strong
es lo mismo que retain
en una statement de propiedad.
Para proyectos ARC usaría strong
lugar de retain
, usaría assign
para propiedades primitivas C y weak
para referencias débiles a objetos Objective-C.
Después de leer tantos artículos de Stackoverflow y aplicaciones de demostración para verificar los atributos de las propiedades de las variables, decidí juntar toda la información de los atributos:
Debajo está el enlace detallado del artículo donde puedes encontrar todos los atributos mencionados anteriormente, que definitivamente te ayudarán. ¡Muchas gracias a todas las personas que dan mejores respuestas aquí!
Atributos o atributos de propiedades variables en iOS
1.strong (iOS4 = retener)
Ejemplo:
@property (strong, nonatomic) ViewController *viewController; @synthesize viewController;
2.weak –
Ejemplo:
@property (weak, nonatomic) IBOutlet UIButton *myButton; @synthesize myButton;
Explicación fuerte y débil, gracias a BJ Homer :
Imagina que nuestro objeto es un perro, y que el perro quiere huir (ser desasignado).
Los indicadores fuertes son como una correa en el perro. Mientras tengas la correa unida al perro, el perro no huirá. Si cinco personas unen su correa a un perro, (cinco punteros fuertes a un objeto), entonces el perro no escapará hasta que las cinco correas estén sueltas.
Los indicadores débiles, por otro lado, son como niños pequeños que señalan al perro y dicen “¡Mira, un perro!” Mientras el perro siga con la correa, los niños pequeños aún pueden ver al perro, y aún así lo señalarán. Sin embargo, tan pronto como todas las correas se separan, el perro huye sin importar cuántos niños pequeños lo señalen.
Tan pronto como el último puntero fuerte (correa) ya no apunta a un objeto, el objeto será desasignado, y todos los punteros débiles se pondrán a cero.
Cuando usamos débil?
El único momento en que desearía usar weak, es si desea evitar 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).
3.retener = fuerte
Ejemplo:
@property (nonatomic, retain) NSString *name; @synthesize name;
4. asignar
Ejemplo:
@property (nonatomic, assign) NSString *address; @synthesize address;
Hasta donde yo sé, strong
y retain
son sinónimos, por lo que hacen exactamente lo mismo.
Entonces, el weak
es casi como assign
, pero se establece automáticamente en cero después de que el objeto, apunta hacia, se desasigna.
Eso significa que puedes simplemente reemplazarlos.
Sin embargo , hay un caso especial que he encontrado, donde tuve que usar assign
, en lugar de weak
. Digamos que tenemos dos propiedades delegateAssign
y delegateWeak
. En ambos se almacena nuestro delegado, que nos posee al tener la única referencia fuerte. El delegado está deslocalizando, por lo que -dealloc
se llama a nuestro método -dealloc
.
// Our delegate is deallocating and there is no other strong ref. - (void)dealloc { [delegateWeak doSomething]; [delegateAssign doSomething]; }
El delegado ya está en proceso de desasignación, pero todavía no se ha desasignado por completo. ¡El problema es que weak
referencias weak
a él ya están anuladas! Property delegateWeak
contiene nil, pero delegateAssign
contiene un objeto válido (con todas las propiedades ya publicadas y anuladas, pero sigue siendo válido).
// 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 funcionan esas variables weak
y cuándo son anuladas.
El documento de Clang sobre el conteo automático de referencias (ARC) de Objective-C explica claramente los modificadores y los calificadores de propiedad:
Hay cuatro calificadores de propiedad:
- __ autoreleasing
- __ fuerte
- __ * unsafe_unretained *
- __ débil
Un tipo no es trivialmente calificado por la propiedad si está calificado con __ autoreleasing , __ strong o __ weak .
Luego hay seis modificadores de propiedad para la propiedad declarada:
- assign implica __ * unsafe_unretained * ownership.
- la copia implica __ fuerte propiedad, así como el comportamiento habitual de la semántica de copia en el colocador.
- retener implica __ fuerte propiedad.
- fuerte implica __ fuerte propiedad.
- * unsafe_unretained * implica __ * unsafe_unretained * propiedad.
- débil implica __ propiedad débil .
Con la excepción de débil , estos modificadores están disponibles en modos que no son ARC.
En términos semánticos, los calificadores de propiedad tienen un significado diferente en las cinco operaciones administradas : Lectura, Asignación, Inicialización, Destrucción y Movimiento, en las que la mayoría de las veces solo nos importa la diferencia en la operación de Asignación.
La asignación ocurre cuando se evalúa un operador de asignación. La semántica varía según la calificación:
- Para __ objetos fuertes , el nuevo puntaje primero se retiene; segundo, el lvalue está cargado de semántica primitiva; tercero, el nuevo punto se almacena en el valor l con semántica primitiva; y finalmente, el viejo pointee es lanzado. Esto no se realiza atómicamente; la sincronización externa se debe usar para hacer esto seguro frente a cargas y tiendas concurrentes.
- Para __ objetos débiles , el lvalue se actualiza para apuntar al nuevo pointee, a menos que el nuevo pointee sea un objeto actualmente en desasignación, en cuyo caso el lvalue se actualiza a un puntero nulo. Esto debe ejecutarse atómicamente con respecto a otras asignaciones al objeto, a leer desde el objeto y al lanzamiento final del nuevo punto.
- Para objetos __ * unsafe_unretained *, el nuevo pointee se almacena en el valor l usando semántica primitiva.
- Para __ objetos de autorrelleno , el nuevo pointee se conserva, se libera automáticamente y se almacena en el valor l usando semántica primitiva.
La otra diferencia en Lectura, Iniciación, Destrucción y Movimiento, consulte la Sección 4.2 Semántica en el documento .
Ejemplo: @property (strong, nonatomic) ViewController * viewController;
@synthesize viewController;
Por defecto, automáticamente se obtiene y se establece en cero
Ejemplo: @property (débil, no atómico) IBOutlet UIButton * myButton;
@synthesize myButton;
Las diferencias entre fuerte y retener:
Las diferencias entre débil y asignar:
strong, weak, assign
atributos de propiedad definir cómo se gestionará la memoria para esa propiedad.
Fuerte significa que la cuenta de referencia se incrementará y la referencia a ella se mantendrá durante la vida del objeto
Débil (referencia no fuerte), significa que estamos apuntando a un objeto pero no aumentando su conteo de referencia. A menudo se usa cuando se crea una relación padre-hijo. El padre tiene una fuerte referencia al niño pero el niño solo tiene una referencia débil al padre.
Cada vez que se usa en var.
Cada vez que se usa en un tipo opcional.
Cambia automáticamente a sí mismo a cero.
Solo lectura , podemos establecer la propiedad inicialmente pero luego no se puede cambiar.
Copiar significa que estamos copiando el valor del objeto cuando se crea. También evita que su valor cambie.