ios objective-c properties atomic nonatomic

ios - ¿Cuál es la diferencia entre los atributos atómicos y no atómicos?



objective-c properties (26)

¿Qué significa atomic y no atomic en las declaraciones de propiedad?

@property(nonatomic, retain) UITextField *userName; @property(atomic, retain) UITextField *userName; @property(retain) UITextField *userName;

¿Cuál es la diferencia operativa entre estos tres?


atómico (por defecto)

Atomic es el valor predeterminado: si no escribe nada, su propiedad es atómica. Se garantiza una propiedad atómica que si intenta leer de ella, obtendrá un valor válido. No ofrece ninguna garantía sobre cuál podría ser ese valor, pero obtendrá buenos datos, no solo memoria basura. Lo que esto le permite hacer es si tiene varios subprocesos o múltiples procesos que apuntan a una sola variable, un subproceso puede leer y otro puede escribir. Si golpean al mismo tiempo, se garantiza que el hilo del lector obtendrá uno de los dos valores: antes del cambio o después del cambio. Lo que el atómico no le ofrece es cualquier tipo de garantía sobre cuál de esos valores podría obtener. Atomic es realmente confundido con ser seguro para subprocesos, y eso no es correcto. Necesitas garantizar la seguridad de tu hilo de otras maneras. Sin embargo, atomic garantizará que si intenta leer, recupere algún tipo de valor.

no atómico

Por otro lado, no atómico, como probablemente puedas adivinar, simplemente significa "no hagas esas cosas atómicas". Lo que pierdes es la garantía de que siempre recibes algo. Si intenta leer en medio de una escritura, podría recuperar datos de basura. Pero, por otro lado, vas un poco más rápido. Debido a que las propiedades atómicas tienen que hacer algo de magia para garantizar que recuperas un valor, son un poco más lentas. Si se trata de una propiedad a la que está accediendo mucho, es posible que desee desplegar a nonatomic para asegurarse de que no está incurriendo en esa penalización de velocidad.

Vea más aquí: https://realm.io/news/tmi-objective-c-property-attributes/


Atómico

Atomic garantiza que el acceso a la propiedad se realizará de manera atómica. Por ejemplo, siempre devuelve un objeto completamente inicializado, cualquier obtención / conjunto de una propiedad en un hilo debe completarse antes de que otro pueda acceder a él.

Si imagina que la siguiente función ocurre en dos subprocesos a la vez, puede ver por qué los resultados no serían agradables.

-(void) setName:(NSString*)string { if (name) { [name release]; // what happens if the second thread jumps in now !? // name may be deleted, but our ''name'' variable is still set! name = nil; } ... }

Pros: La devolución de objetos completamente inicializados cada vez que sea la mejor opción en caso de subprocesos múltiples.

Contras: Rendimiento golpeado, hace la ejecución un poco más lenta

No atómico:

A diferencia de Atomic, no garantiza un retorno de objeto completamente inicializado cada vez.

Pros: Ejecución extremadamente rápida.

Contras: posibilidades de valor de basura en caso de subprocesos múltiples.


Atómico

  • es el comportamiento predeterminado
  • asegurará que el proceso presente sea completado por la CPU, antes de que otro proceso acceda a la variable
  • No es rápido, ya que garantiza que el proceso se complete por completo.

No atómico

  • NO es el comportamiento por defecto
  • más rápido (para código sintetizado, es decir, para variables creadas utilizando @property y @synthesize)
  • no seguro para subprocesos
  • puede resultar en un comportamiento inesperado, cuando dos procesos diferentes acceden a la misma variable al mismo tiempo

Antes de discutir acerca de los atributos de @property, debes saber de qué se trata 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.

Ejemplo:

clase .h

@interface ExampleClass : NSObject @property (nonatomic, retain) NSString *name; @end

.m clase

@implementation ExampleClass @synthesize name; @end

Ahora el compilador sintetizará los métodos de acceso para el nombre.

ExampleClass *newObject=[[ExampleClass alloc]init]; NSString *name1=[newObject name]; // get ''name'' [obj setName:@“Tiger”];

Lista de atributos de @propiedad: atómica. no atómico conservar. dupdo. solo lectura. leer escribir. asignar. fuerte.

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, al mismo tiempo, solo un subproceso de una instancia particular de esa clase puede tener el control sobre ese objeto.

Ejemplo:

@property NSString *name; //by default atomic @property (atomic)NSString *name; // explicitly declared atomic

no atómico: 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;

retener: se requiere cuando el atributo es un puntero a un objeto. El método de establecimiento aumentará el recuento de retenciones del objeto, de modo que ocupará la memoria en el grupo de autorelease. @property (retain)NSString *name;

copia: si usa copia, no puede 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; NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"]; xyzObj.name = nameString; [nameString appendString:@"Pizza"];

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. @property (readonly) NSString *name;

readwrite: es el comportamiento predeterminado. No es necesario especificar explícitamente el atributo de escritura.

@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.

@property (assign) NSInteger year;

fuerte: es un reemplazo para retener. @property (nonatomic, strong) AVPlayer *player;

unsafe_unretained: hay 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;


Atómico significa que solo un hilo accede a la variable (tipo estático). Atomic es seguro para los hilos, pero es lento.

Nonatomic significa que múltiples hilos acceden a la variable (tipo dinámico). No atómico no es seguro para el hilo, pero es rápido.


Atomic es seguro para subprocesos , es lento y asegura (no está garantizado) que solo se proporciona el valor bloqueado, sin importar cuántos subprocesos estén intentando acceder a la misma zona. Cuando se usa atomic, un fragmento de código escrito dentro de esta función se convierte en parte de la sección crítica, a la que solo se puede ejecutar un hilo a la vez.

Solo asegura la seguridad del hilo; no garantiza eso. Lo que quiero decir es que contrata a un conductor experto para su automóvil, pero no garantiza que el automóvil no sufra un accidente. Sin embargo, la probabilidad sigue siendo la más mínima.

Atómico: no se puede descomponer, por lo que se espera el resultado. Con nonatomic: cuando otro hilo accede a la zona de memoria, puede modificarla, por lo que el resultado es inesperado.

Código de conversación:

Atómico hacer getter y setter de la propiedad hilo seguro. por ejemplo, si has escrito:

self.myProperty = value;

es hilo seguro.

[myArray addObject:@"Abc"]

NO es seguro para la rosca.


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

  1. atomic // predeterminado
  2. nonatomic
  3. strong = retain // Predeterminado
  4. weak = unsafe_unretained
  5. retain
  6. assign // predeterminado
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite // Predeterminado

En el artículo Variables de propiedades o modificadores en iOS , puede encontrar todos los atributos mencionados anteriormente, y eso definitivamente lo ayudará.

  1. atomic

    • atomic significa que solo un hilo accede a la variable (tipo estático).
    • atomic es hilo seguro.
    • Pero es lento en el rendimiento.
    • atomic es el comportamiento por defecto
    • Los accesores atómicos en un entorno no recolectado de basura (es decir, cuando se utiliza 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;

  2. nonatomic

    • nonatomic significa acceso múltiple a la variable (tipo dinámico).
    • nonatomic es hilo inseguro.
    • Pero es rápido en el rendimiento.
    • nonatomic NO es un comportamiento por defecto. Necesitamos agregar la palabra clave no nonatomic 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;


El valor predeterminado es atomic , esto significa que le cuesta el rendimiento cuando usa la propiedad, pero es seguro para subprocesos. Lo que hace Objective-C es establecer un bloqueo, por lo que solo el hilo real puede acceder a la variable, siempre que se ejecute el setter / getter.

Ejemplo con MRC de una propiedad con un ivar _internal:

[_internal lock]; //lock id result = [[value retain] autorelease]; [_internal unlock]; return result;

Así que estos dos últimos son los mismos:

@property(atomic, retain) UITextField *userName; @property(retain) UITextField *userName; // defaults to atomic

Por otro lado, no agrega nada nonatomic a tu código. Por lo tanto, solo es seguro para subprocesos si usted mismo codifica el mecanismo de seguridad.

@property(nonatomic, retain) UITextField *userName;

Las palabras clave no tienen que escribirse como primer atributo de propiedad.

No lo olvide, esto no significa que la propiedad en su totalidad sea segura para subprocesos. Solo la llamada al método del setter / getter es. Pero si usas un setter y luego un getter al mismo tiempo con 2 hilos diferentes, ¡también podría romperse!


Encontré una explicación bastante bien explicada de las propiedades atómicas y no atómicas here . Aquí hay un texto relevante de la misma:

''atómico'' significa que no se puede descomponer. En términos de SO / programación, una llamada a una función atómica es una que no puede interrumpirse; toda la función debe ejecutarse, y no debe intercambiarse fuera de la CPU por el cambio de contexto habitual del SO hasta que se complete. En caso de que no lo supiera: dado que la CPU solo puede hacer una cosa a la vez, el sistema operativo rota el acceso a la CPU a todos los procesos en ejecución en poco tiempo, para dar la ilusión de la multitarea. El programador de la CPU puede (y lo hace) interrumpir un proceso en cualquier punto de su ejecución, incluso en una llamada de función media. Por lo tanto, para acciones como la actualización de variables de contador compartidas donde dos procesos podrían intentar actualizar la variable al mismo tiempo, deben ejecutarse ''atómicamente'', es decir, cada acción de actualización debe finalizar en su totalidad antes de que cualquier otro proceso pueda intercambiarse en el UPC.

Así que supongo que, en este caso, atómico significa que los métodos del lector de atributos no pueden interrumpirse, lo que significa que las variables que lee el método no pueden cambiar su valor a la mitad, ya que se obtiene algún otro hilo / llamada / función. Cambiado a la CPU.

Debido a que las variables atomic no se pueden interrumpir, se garantiza que el valor que contienen en cualquier punto (bloqueo de subprocesos) no está dañado , asegurando que este bloqueo de subprocesos hace que el acceso a ellas sea más lento. non-atomic variables non-atomic , por otro lado, no ofrecen tal garantía pero ofrecen el lujo de un acceso más rápido. Para resumir, vaya con non-atomic cuando sepa que varias variables no tendrán acceso a sus variables simultáneamente y acelerará el proceso.


Esto se explica en la documentation de Apple, pero a continuación hay algunos ejemplos de lo que realmente está sucediendo. Tenga en cuenta que no hay una palabra clave "atómica"; si no especifica "no atómica", la propiedad es atómica, pero la especificación "atómica" explícitamente generará un error.

//@property(nonatomic, retain) UITextField *userName; //Generates roughly - (UITextField *) userName { return userName; } - (void) setUserName:(UITextField *)userName_ { [userName_ retain]; [userName release]; userName = userName_; }

Ahora, la variante atómica es un poco más complicada:

//@property(retain) UITextField *userName; //Generates roughly - (UITextField *) userName { UITextField *retval = nil; @synchronized(self) { retval = [[userName retain] autorelease]; } return retval; } - (void) setUserName:(UITextField *)userName_ { @synchronized(self) { [userName_ retain]; [userName release]; userName = userName_; } }

Básicamente, la versión atómica tiene que bloquearse para garantizar la seguridad del subproceso, y también está superando el recuento de referencia en el objeto (y el recuento de autoreleas para equilibrarlo) de modo que se garantice que el objeto existe para la persona que llama, de lo contrario es una condición de carrera potencial si otra hebra está configurando el valor, lo que hace que el recuento de referencia caiga a 0.

En realidad, hay un gran número de variantes diferentes de cómo funcionan estas cosas dependiendo de si las propiedades son valores u objetos escalares, y cómo interactúan retener, copiar, leer solo, no atómico, etc. En general, los sintetizadores de propiedades solo saben cómo hacer lo "correcto" para todas las combinaciones.


La mejor manera de entender la diferencia es usando el siguiente ejemplo.

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 un setter o getter, otros subprocesos esperarán.

Esto hace que la propiedad "nombre" sea segura para lectura / escritura, pero si otro subproceso, D, llama a [name release] simultáneamente, esta operación podría producir un bloqueo porque no hay ninguna llamada de establecimiento / captador involucrada aquí. 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 de subprocesos 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 el caso de atómico, uno de A, B o C se ejecutará primero, pero D todavía puede ejecutarse en paralelo.


La respuesta más fácil primero: no hay diferencia entre los dos segundos ejemplos. Por defecto, los accesores de propiedades son atómicos.

Los accesores atómicos en un entorno no recolectado de basura (es decir, cuando se utiliza retener / liberar / autorelease) usarán un bloqueo para garantizar que otra hebra no interfiera con la configuración / obtención correcta del valor.

Consulte la sección " Rendimiento y subprocesos " de la documentación de Apple Objective-C 2.0 para obtener más información y otras consideraciones al crear aplicaciones de subprocesos múltiples.


La sintaxis y la semántica ya están bien definidas por otras excelentes respuestas a esta pregunta. Debido a que la ejecución y el rendimiento no están bien detallados, agregaré mi respuesta.

¿Cuál es la diferencia funcional entre estos 3?

Siempre había considerado atómico como un defecto bastante curioso. En el nivel de abstracción en el que trabajamos, el uso de propiedades atómicas para una clase como vehículo para lograr un 100% de seguridad en la rosca es un caso de esquina. Para los programas multiproceso realmente correctos, la intervención del programador es casi ciertamente un requisito. Mientras tanto, las características de rendimiento y ejecución aún no se han detallado en profundidad. Después de haber escrito algunos programas muy multiproceso a lo largo de los años, había estado declarando mis propiedades como no nonatomic todo el tiempo porque el atómico no era sensible para ningún propósito. Durante la discusión de los detalles de las propiedades atómicas y no atómicas, esta pregunta hizo algunos perfiles y obtuve algunos resultados curiosos.

Ejecución

De acuerdo. Lo primero que me gustaría aclarar es que la implementación de bloqueo está definida y abstraída por la implementación. Louis usa @synchronized(self) en su ejemplo. He visto esto como una fuente común de confusión. La implementación no utiliza realmente @synchronized(self) ; Utiliza cerraduras de giro a nivel de objeto. La ilustración de Louis es buena para una ilustración de alto nivel utilizando construcciones con las que todos estamos familiarizados, pero es importante saber que no usa @synchronized(self) .

Otra diferencia es que las propiedades atómicas retendrán / liberarán el ciclo de tus objetos dentro del captador.

Actuación

Aquí está la parte interesante: el rendimiento al usar accesos de propiedades atómicas en casos no disputados (por ejemplo, de un solo hilo) puede ser realmente muy rápido en algunos casos. En casos menos que ideales, el uso de accesos atómicos puede costar más de 20 veces la sobrecarga de no nonatomic . Mientras que el caso impugnado con 7 subprocesos fue 44 veces más lento para la estructura de tres bytes ( Core i7 Quad Core de 2,2 GHz, x86_64). La estructura de tres bytes es un ejemplo de una propiedad muy lenta.

Nota interesante: los accesores definidos por el usuario de la estructura de tres bytes fueron 52 veces más rápidos que los accesores atómicos sintetizados; o 84% la velocidad de los accesores sintéticos no atómicos.

Los objetos en los casos impugnados también pueden exceder 50 veces.

Debido a la cantidad de optimizaciones y variaciones en las implementaciones, es bastante difícil medir los impactos del mundo real en estos contextos. Es posible que con frecuencia escuche algo como "Confíe en él, a menos que su perfil y descubra que es un problema". Debido al nivel de abstracción, en realidad es bastante difícil medir el impacto real. Recolectar los costos reales de los perfiles puede llevar mucho tiempo y, debido a las abstracciones, es bastante inexacto. Además, ARC vs MRC puede hacer una gran diferencia.

Así que retrocedamos, sin centrarnos en la implementación de accesos de propiedad, incluiremos a los sospechosos habituales, como objc_msgSend , y examinaremos algunos resultados de alto nivel del mundo real para muchas llamadas a un captador de NSString en casos no NSString (valores en segundos):

  • MRC | no atómico | getters implementados manualmente: 2
  • MRC | no atómico | captador sintetizado: 7
  • MRC | atómico | captador sintetizado: 47
  • ARC | no atómico | captador sintetizado: 38 (nota: los ciclos de ref ref agregados aquí de ARC)
  • ARC | atómico | captador sintetizado: 47

Como probablemente haya adivinado, la actividad / el ciclo de conteo de referencia es un contribuyente significativo con atómica y bajo ARC. También verías mayores diferencias en los casos impugnados.

Aunque presto mucha atención al rendimiento, ¡todavía digo Semántica Primero! . Mientras tanto, el rendimiento es una prioridad baja para muchos proyectos. Sin embargo, conocer los detalles de ejecución y los costos de las tecnologías que utiliza ciertamente no daña. Debe usar la tecnología adecuada para sus necesidades, propósitos y habilidades. Esperamos que esto le ahorre algunas horas de comparaciones y le ayude a tomar una decisión mejor informada al diseñar sus programas.


Los dos últimos son idénticos; "atómico" es el comportamiento predeterminado ( tenga en cuenta que en realidad no es una palabra clave; se especifica solo por la ausencia de nonatomic atomic se agregó como una palabra clave en las versiones recientes de llvm / clang).

Suponiendo que está sintetizando las implementaciones del método, atómico y no atómico cambia el código generado. Si está escribiendo su propio setter / getters, atomic / nonatomic / retain / assign / copy son meramente informativos. (Nota: @synthesize es ahora el comportamiento predeterminado en las versiones recientes de LLVM. Tampoco es necesario declarar variables de instancia; también se sintetizarán automáticamente y tendrán una _ a su nombre para evitar el acceso directo accidental).

Con "atómico", el establecedor / captador sintetizado se asegurará de que siempre se devuelva un valor completo desde el captador o lo establezca, independientemente de la actividad del definidor en cualquier otro hilo. Es decir, si el subproceso A está en el medio del captador, mientras que el subproceso B llama al establecedor, se devolverá al autor de la llamada en un valor real viable (un objeto lanzado automáticamente).

En no nonatomic , no se hacen tales garantías. Por lo tanto, no nonatomic es considerablemente más rápido que "atómico".

Lo que "atómico" no hace es garantizar la seguridad de los hilos. Si el subproceso A llama al captador al mismo tiempo que el subproceso B y C llama al configurador con valores diferentes, el subproceso A puede obtener cualquiera de los tres valores devueltos: el anterior a cualquier llamador o cualquiera de los valores pasados ​​a los configuradores en B y C. Del mismo modo, el objeto puede terminar con el valor de B o C, no hay forma de saberlo.

Asegurar la integridad de los datos, uno de los principales desafíos de la programación de subprocesos múltiples, se logra por otros medios.

Añadiendo a esto:

atomicity de una sola propiedad tampoco puede garantizar la seguridad del subproceso cuando están en juego múltiples propiedades dependientes.

Considerar:

@property(atomic, copy) NSString *firstName; @property(atomic, copy) NSString *lastName; @property(readonly, atomic, copy) NSString *fullName;

En este caso, el hilo A podría cambiar el nombre del objeto llamando a setFirstName: y luego llamando a setLastName: Mientras tanto, el hilo B puede llamar a fullName entre las dos llamadas del hilo A y recibirá el nuevo nombre junto con el apellido anterior.

Para abordar esto, necesita un modelo transaccional . Es decir, algún otro tipo de sincronización y / o exclusión que permite excluir el acceso a fullName mientras se actualizan las propiedades dependientes.


Atómico = seguridad del hilo

No atómico = No hay seguridad de hilo

Seguridad del hilo:

Las variables de instancia son seguras para subprocesos si se comportan correctamente cuando se accede desde múltiples subprocesos, independientemente de la programación o el intercalado de la ejecución de dichos subprocesos en el entorno de ejecución, y sin sincronización adicional u otra coordinación por parte del código de llamada.

En nuestro contexto:

Si un hilo cambia el valor de la instancia, el valor modificado está disponible para todos los hilos, y solo un hilo puede cambiar el valor a la vez.

Donde usar atomic :

si se va a acceder a la variable de instancia en un entorno multiproceso.

Implicación de lo atomic :

No es tan rápido como no nonatomic porque no nonatomic no requiere ningún trabajo de vigilancia en el tiempo de ejecución.

Donde usar nonatomic :

Si la variable de instancia no va a ser cambiada por múltiples hilos, puedes usarla. Mejora el rendimiento.



Propiedades atómicas : cuando una variable asignada con propiedad atómica significa que solo tiene acceso a un subproceso y que será segura para subprocesos y será buena en la perspectiva del rendimiento, tendrá un comportamiento predeterminado.

Propiedades no atómicas : cuando una variable asignada con propiedad atómica significa que tiene acceso a múltiples subprocesos y no será segura para los subprocesos y será lenta en la perspectiva del rendimiento, tendrá un comportamiento predeterminado y cuando dos subprocesos diferentes quieran acceder a la variable al mismo tiempo Dará resultados inesperados.


Atómico: garantice la seguridad de la rosca bloqueando la rosca con NSLOCK.

No atómico: no garantiza la seguridad de subprocesos ya que no hay un mecanismo de bloqueo de subprocesos.


La propiedad atómica garantiza la retención de un valor completamente inicializado, independientemente de la cantidad de subprocesos que estén haciendo getter y setter en él.

La propiedad no atómica especifica 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.


Para simplificar toda la confusión, entendamos el bloqueo mutex. El bloqueo mutex de acuerdo con el nombre bloquea la mutabilidad del objeto. Por lo tanto, si una clase no puede acceder al mismo objeto, otra clase puede acceder al mismo objeto. En iOS @sychronise también proporciona el mutex bloquear. Ahora sirve en modo FIFO y garantiza que el flujo no se vea afectado por dos clases que comparten la misma instancia. Sin embargo, si la tarea está en el hilo principal, evite acceder al objeto utilizando propiedades atómicas, ya que puede contener su interfaz de usuario y degradar el rendimiento.


Antes de comenzar: Debe saber que todos los objetos en la memoria deben ser desasignados de la memoria para que ocurra una nueva escritura. No puedes simplemente escribir sobre algo como lo haces en el papel. Usted debe primero borrar (dealloc) y luego se puede escribir en él. Si en el momento en que se realiza el borrado (o se realiza la mitad) y aún no se ha escrito nada (o la mitad se escribió) e intenta leerlo, ¡podría ser muy problemático! Ayuda atómica y no atómica para tratar este problema de diferentes maneras.

Primero lee this pregunta y luego lee la respuesta de Bbum . Además a continuación, lea mi resumen.

atomic SIEMPRE garantizará

  • Si dos personas diferentes quieren leer y escribir al mismo tiempo, ¡su papel no se quemará! -> Su aplicación nunca se bloqueará, incluso en una condición de carrera.
  • Si una persona está tratando de escribir y solo ha escrito 4 de las 8 letras para escribir, entonces no se puede leer en el medio, la lectura solo se puede hacer cuando las 8 letras están escritas -> No leer (obtener) ocurrirá en ''un hilo que aún está escribiendo'', es decir, si hay que escribir de 8 bytes a bytes, y solo se escriben 4 bytes, hasta ese momento, no se le permite leer. Pero como dije que no se bloquearía, se leería el valor de un objeto lanzado automáticamente .
  • Si antes de escribir ha borrado lo que estaba escrito previamente en un papel y luego alguien quiere leer, todavía puede leer. ¿Cómo? Leerá algo similar a la papelera de Mac OS (ya que la papelera no se ha borrado al 100% ... está en un limbo) ---> Si ThreadA debe leerse mientras ThreadB ya ha reubicado para escribir, podría Obtenga valor del valor final completamente escrito por ThreadB u obtenga algo del conjunto de autorelease.

Los recuentos de retención son la forma en que se gestiona la memoria en Objective-C. Cuando creas un objeto, tiene una cuenta de retención de 1. Cuando envías un mensaje de retención de un objeto, su cuenta de retención se incrementa en 1. Cuando envías un mensaje de liberación a un objeto, su cuenta de retención disminuye en 1. Cuando enviar a un objeto un mensaje de liberación automática , su cuenta de retención se reduce en 1 en algún momento en el futuro. Si el recuento de retención de un objeto se reduce a 0, se desasigna.

  • Atomic no garantiza la seguridad de los hilos, aunque es útil para lograr la seguridad de los hilos. La seguridad de subprocesos es relativa a cómo escribe su código / desde qué cola de subprocesos está leyendo / escribiendo. Solo garantiza multithreading irrompible.

¡¿Esperar lo?! ¿Son diferentes los subprocesos y la seguridad de los hilos ?

Sí.Medios de subprocesamiento múltiple: varios subprocesos pueden leer una parte de los datos compartidos al mismo tiempo y no vamos a fallar, sin embargo, no garantiza que no esté leyendo desde un valor no publicado automáticamente. Con seguridad de subprocesos, se garantiza que lo que lee no se libera automáticamente. La razón por la que no hacemos todo lo atómico por defecto es porque hay un costo de rendimiento y para la mayoría de las cosas no es necesario que la seguridad de los hilos. Algunas partes de nuestro código lo necesitan, y para esas pocas partes debemos escribir nuestro código de una manera segura para subprocesos utilizando bloqueos, exclusión mutua o sincronización.

nonatomic

  • Dado que no existe tal cosa como la Papelera de Mac OS, entonces a nadie le importa si siempre obtiene un valor (<- Esto podría potencialmente provocar un bloqueo), ni a nadie le importa si alguien intenta leer a mitad de su escritura (aunque escribir a mitad de camino en la memoria es muy diferente de escribir a mitad de camino en papel, en la memoria podría darle un valor estúpido y loco, mientras que en el papel solo se ve la mitad de lo que se ha escrito) -> No garantiza que no se bloquee, porque No utiliza el mecanismo de autorelease.
  • ¡No garantiza valores escritos completos para ser leído!
  • Es más rápido que el atómico.

En general son diferentes en 2 aspectos:

  • Accidente o no debido a tener o no tener un conjunto de autorelease.

  • Permitir que se lea justo en medio de un ''valor de escritura o vacío no finalizado'' o que no permita y que solo permita leer cuando el valor está completamente escrito.


Atómico significa que solo un hilo puede acceder a la variable a la vez (tipo estático). Atomic es seguro para los hilos, pero es lento.

Nonatomic significa que múltiples hilos pueden acceder a la variable al mismo tiempo (tipo dinámico). No atómico no es seguro para el hilo, pero es rápido.


La verdad es que utilizan el bloqueo de giro para implementar la propiedad atómica. El código de la siguiente manera:

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) { id oldValue; id *slot = (id*) ((char*)self + offset); if (copy) { newValue = [newValue copyWithZone:NULL]; } else if (mutableCopy) { newValue = [newValue mutableCopyWithZone:NULL]; } else { if (*slot == newValue) return; newValue = objc_retain(newValue); } if (!atomic) { oldValue = *slot; *slot = newValue; } else { spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)]; _spin_lock(slotlock); oldValue = *slot; *slot = newValue; _spin_unlock(slotlock); } objc_release(oldValue); }


Si está utilizando atomic, significa que el hilo será seguro y de solo lectura. Si está usando un método no atómico, significa que los múltiples subprocesos acceden a la variable y no es seguro para el subproceso, pero se ejecuta rápidamente, se realiza una lectura y se escribe las operaciones; Este es un tipo dinámico.


Si está utilizando su propiedad en código de subprocesos múltiples, entonces podrá ver la diferencia entre atributos atómicos y no atómicos. Nonatomic es más rápido que atomic y atomic es seguro para subprocesos, no no atómico.

Vijayendra Tripathi ya ha dado un ejemplo para un entorno de subprocesos múltiples.


  • -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

Cómo declarar:

Como el atómico es por defecto así,

@property (retain) NSString *name;

Y en el archivo de implementación

self.name = @"sourov";

Supongamos que una tarea relacionada con tres propiedades es

@property (retain) NSString *name; @property (retain) NSString *A; @property (retain) NSString *B; self.name = @"sourov";

Todas las propiedades funcionan en paralelo (como asincrónicamente).

Si llamas "nombre" desde el hilo A ,

Y

Al mismo tiempo si llamas

[self setName:@"Datta"]

del hilo B ,

Ahora si * la propiedad de nombre no es atómica entonces

  • Devolverá el valor "Datta" para A
  • Devolverá el valor "Datta" para B

Es por eso que no atómico se llama hilo inseguro, pero es rápido en el rendimiento debido a la ejecución paralela

Ahora si * la propiedad del nombre es atómica

  • Se asegurará el valor "Sourov" para A
  • Luego devolverá el valor "Datta" para B

Es por eso que atomic se llama hilo seguro y por eso se llama lectura-escritura segura

Dicha operación de situación se realizará en serie. Y lento en el rendimiento

- Nonatomic significa acceso múltiple a la variable (tipo dinámico).

- Nonatomic es hilo inseguro.

- pero es rápido en el rendimiento

-Nonatomic no es un comportamiento predeterminado, necesitamos agregar una palabra clave no atómica en el atributo de propiedad.

Para In Swift Confirmando que las propiedades Swift no son atómicas en el sentido de ObjC. Una razón es que piense si la atomicidad por propiedad es suficiente para sus necesidades.

Referencia: https://forums.developer.apple.com/thread/25642

Para obtener más información, visite el sitio web http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html