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

Qué hacer atomic y nonatomic significa en 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?

preguntado el 26 de febrero de 09 a las 00:02

26 Respuestas

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 palabra clave en versiones recientes de llvm / clang).

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

Con "atómico", el setter / getter sintetizado se asegurará de que un todo El valor siempre es devuelto por el captador o establecido por el definidor, 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 definidor, un valor viable real (un objeto liberado automáticamente, muy probablemente) se devolverá al llamador en A.

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

¿Qué hace "atómico" no hacer es garantizar la seguridad de los subprocesos. Si el subproceso A llama al captador simultáneamente con el subproceso B y C llamando al configurador con valores diferentes, el subproceso A puede obtener cualquiera de los tres valores devueltos: el anterior a que se llame a los configuradores o cualquiera de los valores pasados ​​a los establecedores en B y C. Del mismo modo, el objeto puede terminar con el valor de B o C, no hay forma de saberlo.

Garantizar 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 de los subprocesos cuando hay varias propiedades dependientes en juego.

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 setFirstName: y luego llamando setLastName:. Mientras tanto, el hilo B puede llamar 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 permita excluir el acceso a fullName mientras se actualizan las propiedades dependientes.

respondido 28 mar '17, 17:03

Dado que cualquier código seguro para subprocesos hará su propio bloqueo, etc., ¿cuándo querría usar los accesos de propiedad atómica? Me cuesta pensar en un buen ejemplo. - daniel dickison

@bbum Tiene sentido. Me gusta su comentario a otra respuesta de que la seguridad de los subprocesos es más una preocupación a nivel de modelo. De una definición de seguridad de subprocesos de IBM: ibm.co/yTEbjY "Si una clase se implementa correctamente, que es otra forma de decir que se ajusta a su especificación, ninguna secuencia de operaciones (lecturas o escrituras de campos públicos y llamadas a métodos públicos) en objetos de esa clase debería poder poner el objeto en un estado inválido, observar que el objeto está en un estado inválido o violar cualquiera de las invariantes, precondiciones o poscondiciones de la clase ". - ben flynn

Aquí hay un ejemplo similar al de @StevenKramer: tengo un @property NSArray* astronomicalEvents; que enumera los datos que quiero mostrar en la interfaz de usuario. Cuando la aplicación se inicia, el puntero apunta a una matriz vacía, la aplicación extrae datos de la web. Cuando se completa la solicitud web (en un subproceso diferente), la aplicación crea una nueva matriz y luego establece atómicamente la propiedad en un nuevo valor de puntero. Es seguro para subprocesos y no tuve que escribir ningún código de bloqueo, a menos que me falte algo. Me parece bastante útil. - panqueque

@HotLicks Otro divertido; en ciertas arquitecturas (no recuerdo cuál), los valores de 64 bits pasados ​​como argumento pueden pasarse la mitad en un registro y la mitad en la pila. atomic evita lecturas de valor medio de subprocesos cruzados. (Ese fue un error divertido de rastrear). bbum

@congliu Thread A devuelve un objeto sin retain/autorelease baile. El hilo B libera el objeto. El hilo A va auge. atomic asegura que el hilo A tenga una referencia fuerte (un conteo de retención +1) para el valor de retorno. - bbum

Esto se explica en Apple documentación, pero a continuación se muestran algunos ejemplos de lo que realmente está sucediendo.

Tenga en cuenta que no hay una palabra clave "atómico", si no especifica "no atómico", entonces la propiedad es atómica, pero especificar "atómico" explícitamente dará como resultado un error.

Si no especifica "no atómico", entonces la propiedad es atómica, pero aún puede especificar "atómico" explícitamente en versiones recientes si lo desea.

//@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 tener un bloqueo para garantizar la seguridad del subproceso, y también está aumentando el recuento de referencias en el objeto (y el recuento de liberación automática para equilibrarlo) para que se garantice que el objeto existe para la persona que llama, de lo contrario, hay es una condición de carrera potencial si otro subproceso está estableciendo el valor, lo que hace que el recuento de referencias caiga a 0.

En realidad, hay una gran cantidad 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, solo lectura, no atómico, etc. En general, los sintetizadores de propiedades simplemente saben cómo hacer "lo correcto" para todas las combinaciones.

Respondido el 18 de Septiembre de 19 a las 15:09

@Louis Gerbarg: Creo que su versión del setter (no atómico, retener) no funcionará correctamente si intenta asignar el mismo objeto (es decir: userName == userName_) - florín

Su código es un poco engañoso; hay no garantía sobre qué captadores / definidores atómicos están sincronizados. Críticamente,@property (assign) id delegate; no está sincronizado en nada (iOS SDK GCC 4.2 ARM -Os), lo que significa que hay una carrera entre [self.delegate delegateMethod:self]; y foo.delegate = nil; self.foo = nil; [super dealloc];. Vea stackoverflow.com/questions/917884/… - tc.

@fyolnish no estoy seguro de qué _val/val lo son, pero no, en realidad no. El captador de un atómico copy/retain la propiedad debe asegurarse de que no devuelve un objeto cuyo recuento de referencia se vuelve cero debido a que el establecedor es llamado en otro hilo, lo que esencialmente significa que necesita leer el ivar, retenerlo mientras se asegura de que el establecedor no lo haya sobrescrito y liberado y luego suéltelo automáticamente para equilibrar la retención. Eso esencialmente significa ambas el captador y el configurador deben usar un candado (si el diseño de la memoria se corrigió, debería ser factible con instrucciones CAS2; -retain es una llamada a un método). - tc.

@tc Ha pasado bastante tiempo, pero lo que quise escribir probablemente fue esto: gist.github.com/fjolnir/5d96b3272c6255f6baae Pero sí, es posible que un lector lea el valor anterior antes de que setFoo: regrese y lo libere antes de que el lector lo devuelva. Pero tal vez si el colocador usa -autorelease en lugar de -release, eso arreglaría eso. - Fjölnir

@fyolnish Desafortunadamente, no: eso se libera automáticamente en el hilo del setter, mientras que necesita ser liberado automáticamente en el hilo del getter. También parece que hay una posibilidad (pequeña) de quedarse sin pila porque está usando la recursividad. - tc.

Atómico

  • es el comportamiento predeterminado
  • asegurará que el proceso actual 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 predeterminado
  • más rápido (para código sintetizado, es decir, para variables creadas usando @property y @synthesize)
  • no es seguro para subprocesos
  • puede resultar en un comportamiento inesperado, cuando dos procesos diferentes acceden a la misma variable al mismo tiempo

Respondido el 20 de junio de 20 a las 10:06

La mejor forma de comprender la diferencia es utilizando el siguiente ejemplo.

Suponga que hay una propiedad de cadena atómica llamada "nombre", y si llama [self setName:@"A"] desde el hilo A, llamar [self setName:@"B"] desde el hilo B, y llame [self name] desde el subproceso C, 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 hilo, D, llama [name release] simultáneamente, esta operación podría producir un bloqueo porque no hay una llamada de establecedor / 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 los hilos de dichos objetos.

Si la propiedad "nombre" no era atómica, entonces todos los subprocesos en el ejemplo anterior - A, B, C y D se ejecutarán simultáneamente produciendo cualquier resultado impredecible. En caso de atómico, uno de A, B o C se ejecutará primero, pero D aún puede ejecutarse en paralelo.

Respondido el 31 de enero de 16 a las 10:01

La sintaxis y la semántica ya están bien definidas por otras excelentes respuestas a esta pregunta. Porque ejecución y actuación 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 valor predeterminado bastante curioso. En el nivel de abstracción en el que trabajamos, usar propiedades atómicas para una clase como vehículo para lograr el 100% de seguridad en los hilos es un caso de esquina. Para programas multiproceso verdaderamente correctos, es casi seguro que la intervención del programador sea un requisito. Mientras tanto, las características de rendimiento y la ejecución aún no se han detallado en profundidad. Habiendo escrito algunos programas con muchos subprocesos múltiples a lo largo de los años, había estado declarando mis propiedades como nonatomic todo el tiempo porque 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, Hice algunos perfiles y encontré algunos resultados curiosos.

Ejecución

Está bien. 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 Realmente utilizan el @synchronized(self); usa nivel de objeto cerraduras giratorias. La ilustración de Louis es buena para una ilustración de alto nivel usando constructos con los 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 sus objetos dentro del getter.

Performance

Aquí está la parte interesante: rendimiento usando accesos de propiedad atómica en incontestado Los casos (por ejemplo, de un solo subproceso) pueden ser realmente muy rápidos en algunos casos. En casos menos que ideales, el uso de accesos atómicos puede costar más de 20 veces la sobrecarga de nonatomic. Mientras que el Impugnada El caso de usar 7 subprocesos fue 44 veces más lento para la estructura de tres bytes (2.2 GHz Core i7 Cuatro núcleos, x86_64). La estructura de tres bytes es un ejemplo de una propiedad muy lenta.

Nota al margen interesante: los descriptores de acceso definidos por el usuario de la estructura de tres bytes fueron 52 veces más rápidos que los descriptores de acceso atómicos sintetizados; o el 84% de la velocidad de los accesos no atómicos sintetizados.

Los objetos en 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 a menudo escuche algo como "Confíe en él, a menos que haga un perfil y encuentre que es un problema". Debido al nivel de abstracción, en realidad es bastante difícil medir el impacto real. Obtener los costos reales de los perfiles puede llevar mucho tiempo y, debido a las abstracciones, puede resultar bastante impreciso. Además, ARC vs MRC pueden marcar una gran diferencia.

Así que retrocedamos no centrándonos en la implementación de accesos a la propiedad, incluiremos los sospechosos habituales como objc_msgSendy examinar algunos resultados de alto nivel del mundo real para muchas llamadas a un NSString entrar incontestado casos (valores en segundos):

  • MRC | no atómico | captadores implementados manualmente: 2
  • MRC | no atómico | getter sintetizado: 7
  • MRC | atómico | captador sintetizado: 47
  • ARC | no atómico | captador sintetizado: 38 (nota: ARC agrega ciclos de recuento de referencias aquí)
  • ARC | atómico | captador sintetizado: 47

Como probablemente habrá adivinado, la actividad / ciclismo de recuento de referencia es un contribuyente significativo con atómica y bajo ARC. También vería mayores diferencias en los casos impugnados.

Aunque presto mucha atención al rendimiento, sigo diciendo ¡La 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 está de más. Debe utilizar la tecnología adecuada para sus necesidades, propósitos y habilidades. Con suerte, esto le ahorrará algunas horas de comparaciones y le ayudará a tomar una decisión mejor informada al diseñar sus programas.

Respondido 17 Oct 19, 04:10

MRC | atómico | captador sintetizado: 47 ARC | atómico | getter sintetizado: 47 ¿Qué los hace iguales? ¿No debería ARC tener más gastos generales? - SDEZero

Entonces, si las propiedades atómicas son malas, ¿están por defecto? ¿Para aumentar el código repetitivo? - Kunal Balani

@ LearnCocos2D Acabo de probar en 10.8.5 en la misma máquina, apuntando a 10.8, para el caso incontestado de un solo subproceso con un NSString que no es inmortal: -ARC atomic (BASELINE): 100% -ARC nonatomic, synthesised: 94% -ARC nonatomic, user defined: 86% -MRC nonatomic, user defined: 5% -MRC nonatomic, synthesised: 19% -MRC atomic: 102% - los resultados son un poco diferentes hoy. No estaba haciendo nada @synchronized comparaciones @synchronized es semánticamente diferente, y no lo considero una buena herramienta si tiene programas concurrentes no triviales. si necesitas velocidad, evita @synchronized. - Justin

¿tienes esta prueba en línea en alguna parte? Sigo agregando el mío aquí: github.com/LearnCocos2D/LearnCocos2D/tree/master/… - AprendeCocos2D

@ LearnCocos2D no los he preparado para el consumo humano, lo siento. - Justin

Atómico = seguridad del hilo

No atómico = Sin seguridad para hilos

Seguridad del hilo:

Las variables de instancia son seguras para subprocesos si se comportan correctamente cuando se accede a ellas desde varios subprocesos, independientemente de la programación o el entrelazado de la ejecución de esos subprocesos por parte del 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 subproceso cambia el valor de la instancia, el valor modificado está disponible para todos los subprocesos, y solo un subproceso puede cambiar el valor a la vez.

Dónde utilizar atomic:

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

Implicación de atomic:

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

Dónde utilizar nonatomic:

Si la variable de instancia no va a ser cambiada por varios subprocesos, puede usarla. Mejora el rendimiento.

Respondido el 31 de enero de 16 a las 13:01

Todo lo que dice aquí es correcto, pero la última oración es esencialmente "incorrecta", Dura, para la programación de hoy. Es realmente inconcebible que se moleste en intentar "mejorar el rendimiento" de esta manera. (Quiero decir, antes de estar a años luz de eso, estaría "no usando ARC", "¡no usando NSString porque es lento!", Etc.). Para dar un ejemplo extremo, sería como decir "equipo, no pongas ningún comentario en el código, ya que nos ralentiza ". No existe una canalización de desarrollo realista en la que desee obtener ganancias de rendimiento teóricas (inexistentes) por el bien de la falta de fiabilidad. - gordito

Durai, FWIW, que aquí contradice directamente su tesis de "Atómico = seguridad de subprocesos". En el documento, Apple dice explícitamente: "Atomicidad de propiedad no es sinónimo de seguridad de subprocesos de un objeto". En la práctica, la tecnología atómica rara vez es suficiente para lograr la seguridad de los hilos. - Robar

Después de leer tantos artículos, publicaciones de Stack Overflow y hacer aplicaciones de demostración para verificar atributos de propiedades variables, decidí juntar toda la información de 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 Atributos o modificadores de propiedades variables en iOS puedes encontrar todos los atributos mencionados anteriormente, y eso definitivamente te ayudará.

  1. atomic

    • atomic significa que solo un hilo accede a la variable (tipo estático).
    • atomic es seguro para subprocesos.
    • Pero es lento en rendimiento
    • atomic es el comportamiento predeterminado
    • Los accesores atómicos en un entorno sin recolección de basura (es decir, cuando se usa retener / liberar / liberar automáticamente) usarán un bloqueo para asegurarse de que otro hilo no interfiera con la configuración / obtención correcta del valor.
    • En realidad, no es una palabra clave.

    Ejemplo:

        @property (retain) NSString *name;
    
        @synthesize name;
    
  2. nonatomic

    • nonatomic significa que múltiples subprocesos acceden a la variable (tipo dinámico).
    • nonatomic no es seguro para subprocesos.
    • Pero es rápido en rendimiento.
    • nonatomic NO es un comportamiento predeterminado. Necesitamos agregar el nonatomic palabra clave en el atributo de propiedad.
    • Puede resultar en un comportamiento inesperado, cuando dos procesos diferentes (subprocesos) acceden a la misma variable al mismo tiempo.

    Ejemplo:

        @property (nonatomic, retain) NSString *name;
    
        @synthesize name;
    

Respondido el 31 de enero de 16 a las 10:01

¿Cómo pueden asignar y fortalecer / retener ambos valores predeterminados? - OperadorBang

fuerte viene con ARC, la retención era predeterminada antes de ARC - abdullahselek

Encontré una explicación bastante bien formulada de las propiedades atómicas y no atómicas aquí. Aquí hay un texto relevante del mismo:

'atómico' significa que no se puede descomponer. En términos de programación / sistema operativo, una llamada a una función atómica es aquella que no se puede interrumpir; la función completa debe ejecutarse y no se debe cambiar de la CPU por el cambio de contexto habitual del sistema operativo 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 pequeños intervalos de tiempo, para dar la ilusión de multitarea. El programador de la CPU puede (y lo hace) interrumpir un proceso en cualquier punto de su ejecución, incluso en medio de una llamada a la función. Entonces, para acciones como actualizar 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.

Entonces, supongo que atómico en este caso significa que los métodos del lector de atributos no se pueden interrumpir, lo que significa que las variables que está leyendo el método no pueden cambiar su valor a la mitad porque algún otro hilo / llamada / función obtiene intercambiado en la CPU.

Debido a que el atomic Las variables no pueden ser interrumpidas, el valor contenido por ellas en cualquier punto está garantizado (bloqueo de hilo) incorrupto, sin embargo, asegurarse de que este bloqueo de subprocesos sea más lento. non-atomic las variables, por otro lado, no ofrecen tal garantía, pero ofrecen el lujo de un acceso más rápido. Para resumir, ve con non-atomic cuando sepa que varios subprocesos no accederán a sus variables simultáneamente y acelerará las cosas.

Respondido el 17 de junio de 14 a las 06:06

El enlace está roto. ; (- Robar

Ese es el problema con los enlaces :( afortunadamente, he citado el texto relevante en mi respuesta - tipycalFlow

Atómico:

Atomic garantiza que el acceso a la propiedad se realizará de forma atómica. Por ejemplo, siempre devuelve objetos completamente inicializados, 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: El retorno de objetos completamente inicializados cada vez lo convierte en la mejor opción en caso de subprocesos múltiples.

Contras : Impacto en el rendimiento, hace que la ejecución sea un poco más lenta

No atómico:

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

Pros: Ejecución extremadamente rápida.

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

Respondido 17 Jul 16, 23:07

Ese comentario no tiene mucho sentido. ¿Puedes aclarar? Si observa ejemplos en el sitio de Apple, la palabra clave atómica se sincroniza en el objeto mientras actualiza sus propiedades. - Andrew Grant

Primero la respuesta más fácil: no hay diferencia entre los dos segundos ejemplos. De forma predeterminada, los descriptores de acceso a las propiedades son atómicos.

Los accesores atómicos en un entorno sin recolección de basura (es decir, cuando se usa retener / liberar / liberar automáticamente) usarán un bloqueo para asegurarse de que otro hilo no interfiera con la configuración / obtención correcta del valor.

Ver el "Rendimiento y subprocesamiento"sección de la documentación de Objective-C 2.0 de Apple para obtener más información y otras consideraciones al crear aplicaciones multiproceso.

respondido 15 mar '13, 05:03

Dos razones. En primer lugar, para el código sintetizado, genera más rápido (pero no código seguro para subprocesos). En segundo lugar, si está escribiendo descriptores de acceso para clientes que no son atómicos, le permite anotar para cualquier usuario futuro que el código no es atómico cuando están leyendo su interfaz, sin que se implementen. - luis gerbarg

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

No atómico significa que varios subprocesos acceden a la variable (tipo dinámico). Nonatomic no es seguro para subprocesos, pero es rápido.

Respondido el 31 de enero de 16 a las 10:01

Atómico es a salvo de amenazas, es el lento y lo bien asegurado (no 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, en 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 eso no garantiza que el automóvil no sufra un accidente. Sin embargo, la probabilidad sigue siendo mínima.

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

Charla de código:

Atomic make getter y setter del subproceso de propiedad seguro. por ejemplo, si ha escrito:

self.myProperty = value;

es seguro para subprocesos.

[myArray addObject:@"Abc"] 

NO es seguro para subprocesos.

Respondido 02 ago 17, 10:08

No sé cómo viene el último párrafo, pero es simplemente incorrecto, no existe tal cosa como "copia privada". - pico

No existe la palabra clave "atómico".

@property(atomic, retain) UITextField *userName;

Podemos usar lo anterior como

@property(retain) UITextField *userName;

Ver la pregunta de Stack Overflow Tengo problemas si uso @property (atómico, retener) NSString * myString.

contestado el 23 de mayo de 17 a las 12:05

"Existe tal palabra clave", Que la palabra clave no sea requerida por defecto e incluso sea el valor predeterminado no significa que la palabra clave no exista. - matthijn

Esto es incorrecto. La palabra clave existe. Esta respuesta es engañosa y le animo a que la elimine. - sethfri

atómico (predeterminado)

Atómico es el predeterminado: si no escribe nada, su propiedad es atómica. Una propiedad atómica tiene la garantía de 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 que si tiene varios subprocesos o varios procesos apuntando a una sola variable, un subproceso puede leer y otro subproceso puede escribir. Si aciertan 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 atomic no le da es ningún tipo de garantía sobre cuál de esos valores podría obtener. Atomic se confunde comúnmente con ser seguro para subprocesos, y eso no es correcto. Necesita garantizar la seguridad de su hilo de otras formas. Sin embargo, atomic garantizará que si intenta leer, obtendrá algún tipo de valor.

no atómico

Por otro lado, no atómico, como probablemente puedas adivinar, solo significa, "no hagas esas cosas atómicas". Lo que pierdes es esa garantía de que siempre recuperarás algo. Si intenta leer en medio de una escritura, podría recuperar datos 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 recuperará un valor, son un poco más lentas. Si es una propiedad a la que está accediendo mucho, es posible que desee bajar a no atómica para asegurarse de que no está incurriendo en esa penalización por velocidad.

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

Respondido 23 Jul 16, 07:07

El tu préstamo estudiantil is atomic, esto significa que le cuesta rendimiento cada vez que 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;

Entonces estos dos últimos son los mismos:

@property(atomic, retain) UITextField *userName;

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

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

@property(nonatomic, retain) UITextField *userName;

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

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

Respondido el 27 de Septiembre de 13 a las 10:09

  • -Atomic significa que solo un hilo accede a la variable (tipo estático).
  • -Atomic es seguro para subprocesos.
  • -pero es lento en rendimiento

Cómo declarar:

Como atómico es el predeterminado,

@property (retain) NSString *name;

Y en el archivo de implementación

self.name = @"sourov";

Suponga 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 de forma asincrónica).

Si llamas "nombre" desde el hilo A,

Y

Al mismo tiempo si llamas

[self setName:@"Datta"]

de hilo B,

Ahora, si la propiedad * name no es atómica luego

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

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

Ahora, si la propiedad * name es atómica

  • Asegurará el valor "Sourov" para A
  • Entonces devolverá el valor "Datta" para B

Es por eso que atomic se llama seguro para subprocesos y Por eso se llama seguro de lectura y escritura.

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

- No atómico significa que múltiples subprocesos acceden a la variable (tipo dinámico).

- Nonatomic es inseguro para subprocesos.

- pero tiene un rendimiento rápido

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

For In Swift Confirmando que las propiedades de Swift no son atómicas en el sentido de ObjC. Una razón es para 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

Respondido 05 Oct 17, 08:10

Como muchos muchos muchos maaaaany otros han dicho, atomic is NO ¡a salvo de amenazas! Es más resistente para problemas de subprocesos, pero no seguro para subprocesos. Solo garantiza que obtendrá un valor completo, también conocido como un valor "correcto" (nivel binario), pero de ninguna manera garantizará que sea el valor actual y "correcto" para la lógica de su negocio (podría ser un valor pasado y inválido por su lógica). - alejandro ivan

Antes de comenzar: debe saber que todos los objetos de la memoria deben desasignarse de la memoria para que se produzca un nuevo escritor. No puede simplemente escribir encima de algo como lo hace en un papel. Tú debe: primero bórrelo (desbloquéelo) y luego puede escribir en él. Si en el momento que el borrado está hecho (o medio hecho) y nada todavia escrito (o medio escrito) e intentas leerlo, ¡podría ser muy problemático! Atómico y no atómico lo ayudan a tratar este problema de diferentes maneras.

Primera lectura este pregunta y luego lee La respuesta de Bbum. Además, 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 se escriben las 8 letras -> No se leerá (obtendrá) en 'un subproceso que todavía está escribiendo', es decir, si hay 8 bytes a bytes para escribir, y solo se escriben 4 bytes, hasta ese momento, no se le permite leer de él. Pero como dije que no se bloqueará, leería el valor de un liberado automáticamente objeto.
  • If antes Escribiendote tienen borró lo que antes estaba escrito en papel y luego alguien quiere leerte puede todavía leído. ¿Cómo? Estará leyendo algo similar a la papelera de Mac OS (ya que la papelera todavía no está 100% borrada ... está en un limbo) ---> Si ThreadA debe leer mientras que ThreadB ya se ha desasignado para escribir, obtendría un valor del valor final completamente escrito por ThreadB u obtener algo del grupo de liberación automática.

Los recuentos de retención son la forma en que se administra la memoria en Objective-C. Cuando crea un objeto, tiene un recuento de retención de 1. Cuando envía un mensaje de retención a un objeto, su recuento de retención se incrementa en 1. Cuando envía un mensaje de liberación a un objeto, su recuento de retención se reduce en 1. Cuando enviar un objeto un mensaje de liberación automática, su recuento 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.

  • Atómico no se garantizar la seguridad de los subprocesos, aunque es útil para lograr la seguridad de los subprocesos. La seguridad de subprocesos depende de cómo escribe su código / de qué cola de subprocesos está leyendo / escribiendo. Solo garantiza subprocesos múltiples no bloqueables.

¡¿Qué?! Son multihilo y hilo de seguridad ¿diferente?

Si. Multithreading significa: varios subprocesos pueden leer un dato compartido al mismo tiempo y no nos bloquearemos, pero no garantiza que no esté leyendo un valor no liberado automáticamente. Con la seguridad de subprocesos, se garantiza que lo que lee no se publica automáticamente. La razón por la que no hacemos que todo sea atómico de forma predeterminada es que hay un costo de rendimiento y, para la mayoría de las cosas, realmente no se necesita seguridad de subprocesos. Algunas partes de nuestro código lo necesitan y para esas pocas partes, necesitamos escribir nuestro código de una manera segura para subprocesos usando bloqueos, mutex o sincronización.


nonatomic

  • Dado que no existe tal cosa como la Papelera de Mac OS, a nadie le importa si siempre obtienes o no un valor (<- Esto podría provocar un bloqueo), ni a nadie le importa si alguien intenta leer la mitad de tu escritura (aunque escribir a medias en la memoria es muy diferente de escribir a medias en papel, en la memoria podría darte un valor estúpido y loco de antes, mientras que en el papel solo ves la mitad de lo que se ha escrito) -> No garantiza que no se bloquee, porque no utiliza un mecanismo de liberación automática.
  • ¡No garantiza la lectura de los valores escritos completos!
  • Es más rápido que atómico

En general, son diferentes en 2 aspectos:

  • Bloquear o no por tener o no tener un grupo de liberación automática.

  • Permitir que se lea justo en medio de una 'escritura aún no terminada o valor vacío' o no permitir y solo permitir leer cuando el valor es completamente escrito.

Respondido el 17 de junio de 19 a las 14:06

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

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

Respondido el 31 de enero de 16 a las 17:01

Atomicity atomic (predeterminado)

Atómico es el predeterminado: si no escribe nada, su propiedad es atómica. Una propiedad atómica tiene la garantía de 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 que si tiene varios subprocesos o varios procesos apuntando a una sola variable, un subproceso puede leer y otro subproceso puede escribir. Si aciertan 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 atomic no le da es ningún tipo de garantía sobre cuál de esos valores podría obtener. Atomic se confunde comúnmente con ser seguro para subprocesos, y eso no es correcto. Necesita garantizar la seguridad de su hilo de otras formas. Sin embargo, atomic garantizará que si intenta leer, obtendrá algún tipo de valor.

no atómico

Por otro lado, no atómico, como probablemente puedas adivinar, solo significa, "no hagas esas cosas atómicas". Lo que pierdes es esa garantía de que siempre recuperarás algo. Si intenta leer en medio de una escritura, podría recuperar datos 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 recuperará un valor, son un poco más lentas. Si es una propiedad a la que está accediendo mucho, es posible que desee bajar a no atómica para asegurarse de que no está incurriendo en esa penalización por velocidad. Acceso

cortesía https://academy.realm.io/posts/tmi-objective-c-property-attributes/

Los atributos de propiedad de atomicidad (atómicos y no atómicos) no se reflejan en la declaración de propiedad de Swift correspondiente, pero las garantías de atomicidad de la implementación de Objective-C aún se mantienen cuando se accede a la propiedad importada desde Swift.

Entonces, si define una propiedad atómica en Objective-C, seguirá siendo atómica cuando la use Swift.

cortesía https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c

Respondido 01 Jul 19, 09:07

La propiedad atómica asegura retener un valor completamente inicializado independientemente de cuántos subprocesos estén haciendo getter y setter en él.

La propiedad no atómica especifica que los descriptores de acceso sintetizados simplemente establecen o devuelven un valor directamente, sin garantías sobre lo que sucede si se accede a ese mismo valor simultáneamente desde diferentes subprocesos.

Respondido 10 Jul 16, 15:07

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

No atómico significa que varios subprocesos pueden acceder a la variable al mismo tiempo (tipo dinámico). Nonatomic no es seguro para subprocesos, pero es rápido.

Respondido 10 Jul 16, 15:07

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

Respondido 10 Jul 16, 15:07

La verdad es que usan 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);
    }

Respondido el 09 de diciembre de 16 a las 05:12

Para simplificar toda la confusión, entendamos el bloqueo mutex.

El bloqueo mutex, según el nombre, bloquea la mutabilidad del objeto. Entonces, si una clase accede al objeto, ninguna otra clase puede acceder al mismo objeto.

En iOS, @sychronise también proporciona el bloqueo mutex. 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 usando propiedades atómicas, ya que puede contener su interfaz de usuario y degradar el rendimiento.

Respondido el 14 de diciembre de 18 a las 00:12

Atómico: Garantice la seguridad de los subprocesos bloqueando el subproceso con NSLOCK.

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

Respondido 10 Jul 16, 15:07

Propiedades atómicas : - Cuando una variable asignada con propiedad atómica significa que solo tiene un acceso de subproceso y será segura para subprocesos y será buena en perspectiva de 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 subprocesos y será lenta en perspectiva de rendimiento, tendrá un comportamiento predeterminado y cuando dos subprocesos diferentes quieran acceder a la variable al mismo tiempo, dará resultados inesperados.

Respondido 04 ago 18, 12:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.