/ / Co to jest odpowiednik zsynchronizowany w Objective-C? - java, cel-c, singleton, zsynchronizowany

Co to jest odpowiednik zsynchronizowany w Objective-C? - java, cel-c, singleton, zsynchronizowany

Jaki jest odpowiednik java zsynchronizowany w celu c? Chcę być w stanie uczynić moją metodę singleton bezpieczną, więc kiedy zostanie wywołana z 2 różnych wątków, spróbują użyć jej 1 na 1.

+(MyObject*) getSharedObject
{
if(!singleton)
{
singleton = [[MyObject alloc] init];
}
return singleton;
}

Odpowiedzi:

10 dla odpowiedzi № 1

Obj-C ma zsynchronizowaną konstrukcję

-(MyObject*) getSharedObject
{
@synchronized(something)
{
if(!singleton)
{
singleton = [[MyObject alloc] init];
}
return singleton;
}
}

wracając z bloku zsynchronizowanego robi "właściwą" rzecz


9 dla odpowiedzi nr 2

Odpowiedź Joshua jest poprawna, ale wymaga ciebiemieć obiekt do synchronizacji. Zrobienie tego dla singletonu może prowadzić do różnego rodzaju dziwnych warunków wyścigowych, jeśli nie będziesz ostrożny.Standardowy wzór dla singletona polega na zainicjowaniu go w +initialize, za pomocą dispatch_once, co robi to, co trzeba:

static MyObject *singleton = nil;

+ (void)initialize {
static dispatch_once_t pred;
dispatch_once(&pred, ^{ singleton = [[MyObject alloc] init]; } );
}

- (MyObject&)getSharedObject
{
return singleton;
}

8 dla odpowiedzi nr 3

Aby zsynchronizować tworzenie singletonu, powinieneś użyć klasy singleton jako obiektu do synchronizacji. To jest mój zwykły wzór:

+(MyObject*) singleton
{
static MyObject* singleton = nil;
@synchronized([MyObject class])
{
if(singleton == nil)
{
singleton = [[MyObject alloc] init];
}
}
return singleton;
}

Punkty do zapamiętania:

  • Uczyniłem to metodą klasową. Nie musisz tego robić, będzie to metoda instancji.

  • Zwykle w ramach metod klasowych, odwołując się do klasy, używałbyś self (lub [self class] w metodach instancji). Jednak byłoby to niewłaściwe, ponieważ podklasy byłyby synchronizowane przy użyciu innego obiektu do klasy MyObject.

  • Zwróciłem na zewnątrz @synchronize blok. Całkowicie jest w porządku, aby powrócić z wnętrza bloku, ale jeśli to zrobisz, otrzymasz ostrzeżenie o statycznym analizatorze statycznym, mówiąc, że metoda może nie zwrócić wartości.


Edytować

Powyższy wzór jest już dawno przestarzały. Najlepiej używać dispatch_once wzór

+(MyObject*) singleton
{
static dispatch_once_t onceToken;
static MyObject* singleton = nil;

dispatch_once (&onceToken, ^{
singleton = [[MyObject alloc] init];
});
return singleton;
}

-1 dla odpowiedzi № 4

Zgadzam się z obiema odpowiedziami. Ale jeśli chodzi o tworzenie instancji na żądanie, to skorzystam z sugestii Joshua z niewielką modyfikacją za pomocą podwójnego sprawdzania blokady:

if (!singleton)
@synchronized(something)
if (!singleton)
instantiate;

W ten sposób unikniesz niepotrzebnego blokowania po utworzeniu obiektu.