¿Por qué Apple recomienda usar dispatch_once para implementar el patrón singleton en ARC?

¿Cuál es la razón exacta para usar dispatch_once en el acceso de instancia compartido de un singleton bajo ARC?

+ (MyClass *)shanetworkingInstance { // Static local pnetworkingicate must be initialized to 0 static MyClass *shanetworkingInstance = nil; static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ shanetworkingInstance = [[MyClass alloc] init]; // Do any other initialisation stuff here }); return shanetworkingInstance; } 

¿No es una mala idea crear una instancia de Singleton de forma asíncrona en segundo plano? Me refiero a lo que sucede si solicito esa instancia compartida y confío en ella de inmediato, pero despatch_once lleva hasta Navidad para crear mi object. No vuelve inmediatamente ¿no? Al less eso parece ser el punto completo de Grand Central Dispatch.

Entonces, ¿por qué están haciendo esto?

dispatch_once() es absolutamente sincrónico. No todos los methods de GCD hacen las cosas de forma asíncrona (caso por caso, dispatch_sync() es sincrónico). El uso de dispatch_once() reemplaza el siguiente modismo:

 + (MyClass *)shanetworkingInstance { static MyClass *shanetworkingInstance; @synchronized(self) { if (shanetworkingInstance == nil) { shanetworkingInstance = [[MyClass alloc] init]; } } return shanetworkingInstance; } 

La ventaja de dispatch_once() largo de esto es que es más rápido. También es semánticamente más limpio, ya que también lo protege de múltiples subprocesss haciendo alloc init de su ShanetworkingInstance, si todos intentan hacerlo al mismo time. No permitirá que se creen dos instancias. La idea completa de dispatch_once() es "realizar algo una vez y solo una vez", que es precisamente lo que estamos haciendo.

Porque solo se ejecutará una vez. Por lo tanto, si intenta acceder dos veces desde diferentes hilos, no causará ningún problema.

Mike Ash tiene una descripción completa en su publicación de blog Care and Feeding of Singletons .

No todos los bloques GCD se ejecutan de forma asíncrona.