313 votes

Pourquoi Apple recommande d'utiliser dispatch_once pour la mise en œuvre du pattern singleton en vertu de l'ARC?

Quelle est la raison exacte pour l'utilisation de dispatch_once dans l'instance partagée accesseur d'un singleton en vertu de l'ARC?

+ (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;
}

N'est-il pas une mauvaise idée pour instancier le singleton de manière asynchrone dans le fond? Je veux dire qu'advient-il si je demande à ce que l'instance partagée et de compter sur elle immédiatement, mais dispatch_once prend jusqu'à Noël pour créer mon objet? Il ne renvoie pas immédiatement à droite? Au moins, cela semble être le point entier de Grand Central Dispatch.

Alors, pourquoi font-ils cela?

426voto

Kevin Ballard Points 88866

dispatch_once() est absolument synchrone. Pas tous les PGCD les méthodes de faire les choses de manière asynchrone (en l'occurrence, dispatch_sync() est synchrone). L'utilisation de l' dispatch_once() remplace la marche suivante:

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

L'avantage de l' dispatch_once() - dessus c'est que c'est plus rapide. C'est aussi sémantiquement plus propre, car toute idée d' dispatch_once() est "réaliser quelque chose une fois et une seule fois", ce qui est précisément ce que nous faisons.

41voto

Abizern Points 52378

Parce qu'il sera exécuté qu'une fois. Donc, si vous essayez d'accéder à deux reprises de différents threads, il ne cause pas un problème.

Mike Ash a une description complète de ses Soins et l'Alimentation des Singletons blog.

Pas tous les PGCD les blocs sont exécutés de façon asynchrone.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X