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?
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.
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.
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