Dlaczego Apple zaleca użycie dispatch one do implementacji wzorca Singletona pod ARC?

Jaki jest dokładny powód użycia dispatch_once w współdzielonym dostępie instancji Singletona pod 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;
}

Czy nie jest to zły pomysł, aby utworzyć instancję Singletona asynchronicznie w tle? Chodzi mi o to, co się stanie, jeśli zażądam tej współdzielonej instancji i polegam na niej natychmiast, ale dispatch_once trwa do Świąt Bożego Narodzenia, aby utworzyć mój obiekt? Nie wraca od razu, prawda? Przynajmniej o to chodzi w Grand Central Dispatch.

Więc dlaczego robią to?

Author: Erik Godard, 2012-02-02

2 answers

dispatch_once() jest całkowicie synchroniczny. Nie wszystkie metody GCD działają asynchronicznie (w tym przypadku dispatch_sync() jest synchroniczna). Użycie dispatch_once() zastępuje następujący idiom:

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

Zaletą tego jest to, że jest szybszy. Jest również semantycznie czystszy, ponieważ chroni cię również przed wieloma wątkami wykonującymi Alloc INIT twojego sharedInstance--jeśli wszystkie spróbują dokładnie w tym samym czasie. Nie pozwoli na utworzenie dwóch instancji. Cała idea dispatch_once() to " wykonać coś raz i tylko raz", czyli dokładnie to, co robimy.

 411
Author: Kevin Ballard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-07 11:50:24

Ponieważ będzie działać tylko raz. Więc jeśli spróbujesz uzyskać do niego dostęp dwa razy z różnych wątków, nie spowoduje to problemu.

[[0]}Mike Ash ma pełny opis w swoim Pielęgnacja i karmienie singletonów blogu.

Nie wszystkie bloki GCD są uruchamiane asynchronicznie.

 40
Author: Abizern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-02 20:00:10