298 votos

¿Por qué Apple recomienda utilizar dispatch_once para implementar el patrón singleton bajo arco?

¿Cuál es la razón exacta por la que el uso de dispatch_once en la instancia compartida de descriptor de acceso de un singleton en virtud de ARCO?

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

¿No es una mala idea para crear una instancia del singleton de forma asincrónica en el fondo? Me refiero a ¿qué sucede si me solicitar que la instancia compartida y confiar en él de inmediato, pero dispatch_once lleva hasta la Navidad para crear mi objeto? No regresa inmediatamente a la derecha? Al menos ese parece ser el punto principal de la Grand Central Dispatch.

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

412voto

Kevin Ballard Puntos 88866

dispatch_once()es absolutamente sincrónico. No todos los métodos de GCD hacen las cosas de forma asincrónica (en este caso, dispatch_sync() es sincrónico). El uso de dispatch_once() reemplaza el idioma siguiente:

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

La ventaja de dispatch_once() sobre esto es que es más rápido. También es semánticamente más limpio, porque la idea entera de dispatch_once() es "realizar algo una vez y solamente una vez", que es precisamente lo que estamos haciendo.

40voto

Abizern Puntos 52378

Porque sólo se ejecutará una vez. Así que si intentas acceder dos veces desde diversos hilos de rosca que no causará un problema.

Mike Ash tiene una descripción completa en su blog de cuidado y alimentación de solteros .

No todos los bloques de GCD se ejecutan asincrónicamente.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X