2009-08-21 15 views
8

Zastanawiam się, gdzie jest najlepsze miejsce do inicjowania członków klasy singleton.Kakao - Obiekt Singleton: Gdzie zainicjować zmienne składowe?

Używam wdrożenia podstawowego singleton firmy Apple. Czy mógłbyś wskazać, w którym wierszu pojawiają się inicjały? Kod jest następujący:

static MyGizmoClass *sharedGizmoManager = nil; 

+ (MyGizmoClass*)sharedManager 
{ 
    @synchronized(self) { 
     if (sharedGizmoManager == nil) { 
      [[self alloc] init]; // assignment not done here 
     } 
    } 
    return sharedGizmoManager; 
} 

+ (id)allocWithZone:(NSZone *)zone 
{ 
    @synchronized(self) { 
     if (sharedGizmoManager == nil) { 
      sharedGizmoManager = [super allocWithZone:zone]; 
      return sharedGizmoManager; // assignment and return on first allocation 
     } 
    } 
    return nil; //on subsequent allocation attempts return nil 
} 

- (id)copyWithZone:(NSZone *)zone 
{ 
    return self; 
} 

- (id)retain 
{ 
    return self; 
} 

- (unsigned)retainCount 
{ 
    return UINT_MAX; //denotes an object that cannot be released 
} 

- (void)release 
{ 
    //do nothing 
} 

- (id)autorelease 
{ 
    return self; 
} 
+2

Możesz przeczytać http://boredzo.org/blog/archives/2009-06-17/doing-it-wrong. Czy naprawdę chcesz singleton, który zastępuje wydanie? To tylko maskuje błędy. –

+0

Zanim przypomnisz Jona Hessa, że ​​śledzisz dokumenty Apple'a: Napisałem ten wpis właśnie w odpowiedzi na dokumenty Apple. –

+0

Warto również zauważyć, że klasy nie mają żadnych "członków". Najbliższym, jakie można uzyskać, jest zmienna statyczna w pliku implementacyjnym klasy. A członkowie klasy nie są tym, co i tak chcesz zainicjować. Miałeś na myśli zmienne * instance * instancji singleton *. –

Odpowiedz

18

To jak ze zwykłych zajęć - dodaj ten powyżej bloku:

-(id)init { 
    if (self = [super init]) { 
    // do init here 
    } 

    return self; 
} 

To będzie wywoływana, gdy Singleton jest dostępny po raz pierwszy.

+0

jeśli utworzę tę metodę init, to będzie dostępny prosto bez przechodzenia przez sharedManager, prawda? Teraz, jeśli zrobię to prywatnie, to nie zastąpi metody init(), prawda? –

+0

Tak, jest dostępny bezpośrednio, ale nie sądzę, że tak powinno być - singleton upewni się, że zostanie wywołany po raz pierwszy, kiedy jest potrzebny. Wystarczy jak zwykle zadzwonić [[MySingletonClass sharedClass]] ... – Rudi

+0

+1, jak zauważył Jon Hess, generalnie nie powinno się przeciążać wszystkich tych metod, chyba że naprawdę musisz upewnić się, że istnieje tylko jedna instancja tego obiektu . To bardzo rzadko w praktyce. Zwykle po prostu chcesz ułatwić dostęp do współdzielonego, a do tego wystarczy zaimplementować metodę + sharedInstance (lub + sharedManager lub inną), która zwraca statyczną instancję, i nie martw się, jeśli osoba dzwoniąca wyraźnie zażąda unikalnej instancja. –

1

Można zainicjować je w metodzie init, tak jak każdej innej klasie.

Pamiętaj jednak, że jeśli twój singleton zawiera państwo członkowskie, może nie być już bezpieczny dla wątków. Ponieważ singleton jest dostępny w dowolnym miejscu aplikacji, może być dostępny z różnych wątków.

Powiązane problemy