ios - puede - @propiedad retener, asignar, copiar, no atómica en Objective-C
swift 2 (4)
Como alguien que es nuevo en Objective-C, ¿alguien puede darme una descripción general de retener, asignar, copiar y cualquier otra cosa que falte, que siga la directiva @property? ¿Qué están haciendo y por qué querría usar uno sobre el otro?
Antes de conocer los atributos de @property, debe saber cuál es el uso de @property.
@property ofrece una manera de definir la información que una clase pretende encapsular. Si declara un objeto / variable usando @property , entonces ese objeto / variable será accesible a otras clases que importan su clase.
Si declara un objeto usando @property en el archivo de encabezado, entonces tiene que sintetizarlo usando @synthesize en el archivo de implementación. Esto hace que el objeto sea compatible con KVC . Por defecto, el compilador sintetizará métodos de acceso para este objeto.
Los métodos de acceso son: setter y getter.
Ejemplo: .h
@interface XYZClass : NSObject
@property (nonatomic, retain) NSString *name;
@end
.metro
@implementation XYZClass
@synthesize name;
@end
Ahora el compilador sintetizará los métodos de acceso para el nombre .
XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get ''name''
[obj setName:@"liza"]; // first letter of ''name'' becomes capital in setter method
Lista de atributos de @property
atómico, no atómico, retener, copiar, solo lectura, readwrite, asignar, fuerte, getter = método, setter = método, unsafe_unretained
atómico es el comportamiento por defecto. Si un objeto se declara como atómico, se vuelve seguro para subprocesos. Seguro para subprocesos significa que, a la vez, solo un subproceso de una instancia particular de esa clase puede tener el control sobre ese objeto.
Si el subproceso está realizando el método getter, el otro subproceso no puede realizar el método de establecimiento en ese objeto. Es lento.
@property NSString *name; //by default atomic`
@property (atomic)NSString *name; // explicitly declared atomic`
- nonatomic no es seguro para subprocesos. Puede usar el atributo de propiedad no atómica para especificar que los accesores sintetizados simplemente establecen o devuelven un valor directamente, sin garantías sobre lo que sucede si se accede al mismo valor simultáneamente desde diferentes subprocesos.
Por esta razón, es más rápido acceder a una propiedad no atómica que a una atómica.
@property (nonatomic)NSString *name;
- se requiere la retención cuando el atributo es un puntero a un objeto.
El método de establecimiento aumentará la cantidad de retenciones del objeto, de modo que ocupará la memoria en el conjunto de autorelease.
@property (retain)NSString *name;
- copiar Si usas copia, no puedes usar retener. El uso de copia de la instancia de la clase contendrá su propia copia.
Incluso si se establece una cadena mutable y se modifica posteriormente, la instancia captura cualquier valor que tenga en el momento en que se establece. No se sintetizarán métodos setter y getter.
@property (copy) NSString *name;
ahora,
NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];
xyzObj.name = nameString;
[nameString appendString:@"Pizza"];
El nombre no se verá afectado.
- readonly Si no desea permitir que la propiedad se modifique a través del método de establecimiento, puede declarar la propiedad de solo lectura.
El compilador generará un getter, pero no un setter.
@property (readonly) NSString *name;
- readwrite es el comportamiento predeterminado. No es necesario especificar explícitamente el atributo de escritura.
Es lo contrario de readonly.
@property (readwrite) NSString *name;
- asignar generará un definidor que asigna el valor a la variable de instancia directamente, en lugar de copiarlo o retenerlo. Esto es mejor para los tipos primitivos como NSInteger y CGFloat, u objetos que no posee directamente, como los delegados.
Tenga en cuenta que retener y asignar son básicamente intercambiables cuando la recolección de basura está habilitada.
@property (assign) NSInteger year;
- fuerte es un reemplazo para retener.
Viene con ARC.
@property (nonatomic, strong) AVPlayer *player;
- getter = method Si desea usar un nombre diferente para un método getter, es posible especificar un nombre personalizado agregando atributos a la propiedad.
En el caso de las propiedades booleanas (propiedades que tienen un valor SÍ o NO), es habitual que el método getter comience con la palabra "es"
@property (getter=isFinished) BOOL finished;
- setter = method Si desea usar un nombre diferente para un método setter, es posible especificar un nombre personalizado agregando atributos a la propiedad.
El método debe terminar con dos puntos.
@property(setter = boolBool:) BOOL finished;
- unsafe_unretained Existen algunas clases en Cocoa y Cocoa Touch que aún no admiten referencias débiles, lo que significa que no puede declarar una propiedad débil o una variable local débil para realizar un seguimiento de ellas. Estas clases incluyen NSTextView, NSFont y NSColorSpace, etc. Si necesita usar una referencia débil para una de estas clases, debe usar una referencia no segura.
Una referencia no segura es similar a una referencia débil porque no mantiene vivo el objeto relacionado, pero no se establecerá en nulo si el objeto de destino se desasigna.
@property (unsafe_unretained) NSObject *unsafeProperty;
Si necesita especificar múltiples atributos, simplemente inclúyalos como una lista separada por comas, como esto:
@property (readonly, getter=isFinished) BOOL finished;
El artículo vinculado a MrMage ya no funciona. Entonces, esto es lo que he aprendido en mi (muy) corto tiempo de codificación en Objective-C:
No atómico vs. atómico: el valor predeterminado es "atómico". Siempre use "no atómico". No sé por qué, pero el libro que leí decía que "rara vez hay una razón" para usar "atómico". (Por cierto: el libro que leí es el libro "Programación de iOS" de BNR).
readwrite vs. readonly: "readwrite" es el valor predeterminado. Cuando @synthesize, se crearán tanto un captador como un definidor. Si utiliza "readonly", no se creará ningún definidor. Úselo para un valor que no quiera cambiar después de la instanciación del objeto.
retener vs. copiar vs. asignar
- "asignar" es el valor predeterminado. En el definidor creado por @synthesize, el valor simplemente se asignará al atributo. Entiendo que "asignar" se debe usar para atributos que no son punteros.
- "retener" es necesario cuando el atributo es un puntero a un objeto. El setter generado por @synthesize retendrá (también agregará una cuenta de retención) el objeto. Deberá liberar el objeto cuando haya terminado con él.
- "Copia" es necesaria cuando el objeto es mutable. Use esto si necesita el valor del objeto tal como está en este momento, y no desea que ese valor refleje los cambios realizados por otros propietarios del objeto. Deberá liberar el objeto cuando haya terminado con él porque está reteniendo la copia.
Se puede acceder a la propiedad atómica solo por un hilo a la vez. Es hilo seguro . El valor predeterminado es atómico. Tenga en cuenta que no hay una palabra clave atómica
No atómico significa que varios subprocesos pueden acceder al elemento. Es un subproceso inseguro
Por lo tanto, uno debe tener mucho cuidado al usar atómica. Como afecta el rendimiento de su código
Después de leer muchos artículos, decidí juntar toda la información de los atributos:
- atómico // predeterminado
- no atómico
- fuerte = retener // por defecto
- débil = unsafe_unretained
- conservar
- asignar // predeterminado
- unsafe_unretained
- dupdo
- solo lectura
- readwrite // predeterminado
A continuación se muestra un enlace al artículo detallado donde puede encontrar estos atributos.
Muchas gracias a todas las personas que dan las mejores respuestas aquí !!
Aquí está la descripción de la muestra del artículo
- atómico -Atómico significa que solo un hilo accede a la variable (tipo estático). -Atómico es hilo seguro. -pero es lento en el rendimiento -el comportamiento predeterminado es atómico -los accesores atómicos en un entorno no recolectado como basura (es decir, cuando se usa retener / liberar / autorelease) usarán un bloqueo para garantizar que otra hebra no interfiera con la configuración / obtención correcta del valor. -No es realmente una palabra clave.
Ejemplo:
@property (retain) NSString *name;
@synthesize name;
- nonatomic -Nonatomic significa que múltiples hilos acceden a la variable (tipo dinámico). -Nonatomic es hilo inseguro. -pero es rápido en rendimiento -Nonatomic no es un comportamiento predeterminado, necesitamos agregar una palabra clave no atómica en el atributo de propiedad. -puede resultar en un comportamiento inesperado, cuando dos procesos diferentes (hilos) acceden a la misma variable al mismo tiempo.
Ejemplo:
@property (nonatomic, retain) NSString *name;
@synthesize name;
Explique:
Supongamos que hay una propiedad de cadena atómica llamada "nombre", y si llama a [self setName: @ "A"] desde el hilo A, llame a [self setName: @ "B"] desde el hilo B, y llame a [self name] desde subproceso C, entonces todas las operaciones en diferentes subprocesos se realizarán en serie, lo que significa que si un subproceso está ejecutando setter o getter, otros subprocesos esperarán Esto hace que la propiedad "nombre" sea de lectura / escritura segura, pero si otro subproceso D llama [release de nombre] simultáneamente, esta operación podría producir un bloqueo porque no hay aquí una llamada de establecimiento / captador. Lo que significa que un objeto es seguro para lectura / escritura (ATOMIC) pero no seguro para subprocesos ya que otros subprocesos pueden enviar simultáneamente cualquier tipo de mensajes al objeto. El desarrollador debe garantizar la seguridad del hilo para tales objetos.
Si la propiedad "nombre" no era atómica, entonces todos los subprocesos del ejemplo anterior: A, B, C y D se ejecutarán simultáneamente y producirán un resultado impredecible. En caso de ser atómico, cualquiera de A, B o C se ejecutará primero, pero D aún puede ejecutarse en paralelo.
- fuerte (iOS4 = retener) -dice "mantén esto en el montón hasta que no lo señale más" -en otras palabras "soy el dueño, no puedes desasignar esto antes de apuntar bien con eso mismo para retener" - Usas fuerte solo si necesitas retener el objeto. -Por defecto, todas las variables de instancia y las variables locales son punteros fuertes. -En general, usamos fuerte para UIViewControllers (los padres de los elementos de la interfaz de usuario). -Strong se usa con ARC y, básicamente, lo ayuda a usted, al no tener que preocuparse por el recuento de un objeto. ARC lo libera automáticamente para usted cuando haya terminado con él. El uso de la palabra clave fuerte significa que usted posee el objeto.
Ejemplo:
@property (strong, nonatomic) ViewController *viewController;
@synthesize viewController;
- débil (iOS4 = unsafe_unretained): dice "mantén esto mientras alguien más lo apunte con fuerza", lo mismo que asignar, no retener o liberar. Una referencia "débil" es una referencia que no conservas. -En general, usamos débil para IBOutlets (UIViewController''s Childs). Esto funciona porque el objeto secundario solo necesita existir mientras el objeto principal lo haga. -una referencia débil es una referencia que no protege el objeto referenciado de la colección por un recolector de basura. -La debilidad es esencialmente asignar, una propiedad no retenida. Excepto cuando el objeto se desasigna, el puntero débil se establece automáticamente en nulo
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). Punteros fuertes son como una correa en el perro. Mientras tengas la correa atada al perro, el perro no huirá. Si cinco personas atan su correa a un perro, (cinco punteros a un objeto), entonces el perro no huirá hasta que las cinco correas estén sueltas. 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é en la correa, los niños pequeños todavía pueden ver al perro, y todavía lo señalarán. 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 se desasignará y todos los punteros débiles se pondrán a cero. Cuando usamos débil? La única vez que querría usar debilidad es si quisiera evitar los ciclos de retención (por ejemplo, el padre retiene al niño y el niño retiene al padre para que ninguno sea liberado).
- retener = fuerte - se retiene, se libera el valor antiguo y se asigna - la retención especifica que el nuevo valor debe enviarse - la retención en la asignación y el valor antiguo enviado - liberación - la retención es lo mismo que fuerte. -apple dice que si escribe retener, se convertirá automáticamente / solo funcionará como fuerte. -Métodos como "alloc" incluyen una "retención" implícita
Ejemplo:
@property (nonatomic, retain) NSString *name;
@synthesize name;
- asignar- asignación es el valor predeterminado y simplemente realiza una asignación variable-asignación es un atributo de propiedad que le dice al compilador cómo sintetizar la implementación del establecedor de la propiedad. Yo usaría asignar para propiedades primitivas C y débil para referencias débiles a objetos Objective-C.
Ejemplo:
@property (nonatomic, assign) NSString *address;
@synthesize address;
unsafe_unretained
-unsafe_unretained es un calificador de propiedad que le dice a ARC cómo insertar retener / liberar llamadas -unsafe_unretained es la versión de ARC de asignar.
Ejemplo:
@property (nonatomic, unsafe_unretained) NSString *nickName;
@synthesize nickName;
- se requiere copia-copia cuando el objeto es mutable. -copia especifica que el nuevo valor debe enviarse -copia en la asignación y el valor antiguo enviado -release. -copy es como retener devuelve un objeto que debe liberar explícitamente (por ejemplo, en dealloc) en entornos recolectados sin basura. -si usa copia, todavía necesita liberar eso en dealloc. -Utilice esto si necesita el valor del objeto tal como está en este momento, y no desea que ese valor refleje los cambios realizados por otros propietarios del objeto. Deberá liberar el objeto cuando haya terminado con él porque está reteniendo la copia.
Ejemplo:
@property (nonatomic, copy) NSArray *myArray;
@synthesize myArray;