ultima tutorial objective logo español objective-c

tutorial - ¿Por qué "atómico" es un calificador @property por defecto en Objective C cuando me encuentro usando nonatomic el 100% del tiempo?



objective c vs c++ (5)

En mis pocos años como desarrollador de iOS, no creo haber usado Atomic en una propiedad. Si puedo ver posibles condiciones de carrera o problemas de integridad de los datos debido al enhebrado, el uso de atomic en una propiedad @ nunca ayudaría. Utilizo técnicas convencionales de seguridad de hilos de transacción / unidad de trabajo (usando mecanismos bloqueos, semáforos o lo que sea).

¿Alguien tiene (o conoce) algún ejemplo práctico de dónde se usa atómico ? (Me encantaría ver algunos ejemplos de códigos reales / prácticos)

Después de escribir no atómico por quizás la mil millonésima vez, también me pregunto por qué Apple decidió hacer atómico el predeterminado.


Cuando Apple introdujo por primera vez el concepto de propiedades, hubo un gran argumento acerca de si atomic o no nonatomic debería ser el predeterminado y el pueblo atómico ganó.

Creo que el razonamiento es que en un entorno enhebrado, a menos que la propiedad sea atómica, no se puede garantizar que el puntero que devuelve sea válido. Un getter no atómico se implementaría algo como esto

-(MyObj*) someProperty { return someInstVar; }

Es posible que algún otro subproceso pueda desasignar el objeto apuntado por someInstVar después de que el puntero se haya colocado en el registro para devolver pero antes de que el llamador haya tenido tiempo de retenerlo. Incluso esto no es bueno:

-(MyObj*) someProperty { return [[someInstVar retain] autorelease]; }

porque algún otro subproceso podría desasignar someInstVar justo antes de que se incremente el recuento de retención.

La única forma de devolver el puntero de forma segura en un entorno multiproceso es algo como esto:

-(MyObj*) someProperty { @synchronized(self) { return [[someInstVar retain] autorelease]; } }

y también para sincronizar el setter también.

Sin embargo, el problema es que el bloqueo es muy costoso (en realidad usaron algo mucho más ligero que @sincronizado pero sigue siendo caro) así que todo el mundo estaba usando no atómico de todos modos y simplemente hacer todas las propiedades atómicas no confiere seguridad de hilo en general por lo tanto, se requieren otras técnicas de todos modos y tienden a obviar el problema que discutí anteriormente.

Hay muchas personas que piensan que se tomó una decisión equivocada sobre cuál debería ser el valor predeterminado, pero ahora no se puede cambiar por compatibilidad con versiones anteriores. Me encuentro escribiendo no nonatomic sin siquiera pensar ahora.


En cuanto al primer problema que tienes, tal vez sea porque

Aunque "atómico" significa que el acceso a la propiedad es seguro para subprocesos, simplemente hacer que todas las propiedades de tu clase sean atómicas no significa que tu clase o más generalmente tu gráfico de objetos sea "seguro para subprocesos": la seguridad de subprocesos no se puede expresar en el nivel de métodos de acceso individuales.

En cuanto a por qué Apple lo convierte en atómico por defecto, no creo que haya una buena razón, simplemente fue una mala decisión de diseño. Los chicos en las sesiones de la WWDC alentaron repetidamente a las personas a utilizar métodos no atómicos siempre que sea posible para eliminar el impacto en el rendimiento.


En dos palabras: seguridad de hilo. La mayoría de las aplicaciones que escribimos de manera regular son bastante simples y, como tales, en realidad van a beneficiarse al no tener bloqueos adicionales.

Del lenguaje de programación The Objective-C de Apple:

Las propiedades son atómicas por defecto, de modo que los accesos sintetizados proporcionan un acceso sólido a las propiedades en un entorno multiproceso: es decir, el valor devuelto por el captador o establecido a través del colocador siempre se recupera o establece completamente, independientemente de qué otros hilos se ejecuten simultáneamente. Para obtener más detalles, consulte " Rendimiento y enhebrado ".

Si no especifica valores no atómicos, en un entorno contado de referencia, un acceso de obtención sintetizado para una propiedad de objeto usa un bloqueo y conserva y libera automáticamente el valor devuelto; la implementación será similar a la siguiente:

[_internal lock]; // lock using an object-level lock id result = [[value retain] autorelease]; [_internal unlock]; return result;

Si especifica no atómico, un descriptor de acceso sintetizado para una propiedad de objeto simplemente devuelve el valor directamente.


Las llamadas atómicas son llamadas que no se pueden interrumpir. Toda la llamada debe ser ejecutada.

Actualizar algo así como una variable de contador compartido sería algo que podría ser atómico porque no querría que dos procesos intenten acceder a la variable al mismo tiempo. Las acciones deberían ejecutarse "atómicamente".

Hay una gran cantidad de información útil en esta publicación SO: propiedades atómicas vs no atómicas en cuanto a cuáles son las diferencias y los problemas de seguridad de subprocesos atómicos vs no atómicos.


Vale la pena señalar que bajo la recolección de basura, casi todos los accesores sintetizados son intrínsecamente atómicos: no habría diferencia entre la versión atómica y la no atómica, ya que la asignación simple de un puntero es todo lo que se requiere en ambos casos. Como realmente no se puede hacer un acceso sintetizado no atómico en la recolección de elementos no utilizados, es posible que hayan decidido que tiene más sentido simplemente tener cosas atómicas por defecto.

No tengo ninguna evidencia de que este fuera el razonamiento detrás de la decisión, pero tiene sentido para mí.

(En caso de que tenga curiosidad, todavía hay casos en la recolección de basura donde la asignación simple no es atómica, esto sucede cuando el valor es mayor que el tamaño de la palabra del proceso. En la práctica, eso solo ocurre con las estructuras).

Editar: fuentes añadidas

Puede encontrar más información sobre la atomicidad de las propiedades sintetizadas en la recolección de elementos no utilizados en El lenguaje de programación Objective-C -> Propiedades declaradas -> Rendimiento y subprocesamiento , donde dice "En un entorno recolectado, la mayoría de los métodos sintetizados son atómicos sin incurrir en esta sobrecarga " La atomicidad inherente se menciona más explícitamente en la sesión 420 de la WWDC 420 "Uso de la recolección de basura con Objective-C", alrededor de la marca de los 29 minutos.