2009-11-21 9 views
27

Tengo un bloque de código al que se accede con frecuencia y desde el hilo principal o varios otros hilos de fondo. Necesito asegurarme de que este código solo se procese de a uno por vez.@synchronized() y NSLock diferencias

Actualmente estoy usando un bloque @synchronized(self) { } pero no estoy seguro si eso proporciona la protección correcta. ¿Cómo difiere de una instancia de NSLock?

Finalmente, ¿alguien puede sugerir cómo puedo proteger mi método? El método está en mi aplicación delegue, y acceder a ella desde varios subprocesos llamando:

[[[UIApplication sharedApplication] delegate] myMethod]; 

Muchas gracias,

Mike

Respuesta

30

Hay una gran entrada de blog en el blog de Google Mac acerca de la funcionamiento interno de @synchronized:
http://googlemac.blogspot.com/2006/10/synchronized-swimming.html

Actualmente estoy usando un @synchro nized (self) {} block pero estoy no estoy seguro si eso proporciona la protección correcta . ¿Cómo difiere de una instancia de NSLock?

Existen varias formas de sincronizar secciones críticas (@synchronized, NSLock, OSSpinLock, ...).
Creo que @synchronized es el enfoque más conveniente (and also the slowest).
Here is a good SO answer que explica las diferencias entre @synchronized y NSLock.

Está accediendo a su método a través de un instancias compartidas (que básicamente es un singleton) delegado. Tal vez pueda reconsiderar su diseño y descubrir una forma que le permita bloquear un código más pequeño dentro de myMethod.

+0

¡Gracias por su ayuda! ¿Es correcto usar siempre "self"? Self en este caso apuntará al delegado de la aplicación, no importa cómo lo llame. ¡Estoy confundido sobre por qué tienes que pasar algo! –

+2

Utiliza (auto) si desea bloquear "por instancia" y [Clase de clase de clase] si desea bloquear "por clase". (self) significa que la ejecución de la sección crítica debe sincronizarse para el objeto actual (particular). –

+0

¡Ahhh, lo entiendo! Muchas gracias :-) –

16

Si realmente tiene algo que desea que se procese un elemento a la vez, mi recomendación es usar NSOperations y un NSOperationQueue donde haya establecido maxConcurrentOperationCount en 1. Si se asegura de que la única forma en que se accede a este bloque compartido de código a través de las operaciones en esta cola, eliminará la necesidad de bloqueos costosos.

Esto puede requerir una pequeña reorganización de su aplicación, pero he descubierto que aplicar esto dentro de mis propias aplicaciones ha conducido a un mejor rendimiento y un código más limpio.

+0

+1, sin embargo, uno debe darse cuenta de que la 'pequeña reorganización' requeriría que su código sea completamente asincrónico por naturaleza. @synchronized está destinado a ser un bloqueo de bloqueo síncrono, mientras que el uso de una cola significaría que el sitio de llamada no debería esperar un valor devuelto, sino que usará devoluciones de llamada de bloque para procesar los resultados. Esto puede no ser ideal en secciones críticas de su código donde se esperan llamadas de bloqueo. – strangetimes

Cuestiones relacionadas