2011-01-05 12 views
5

mam Singleton skonfigurować tak:Użyj Singleton In Interface Builder?

static Universe *instance; 

+ (Universe *)instance { return instance; } 

+ (void)initialize 
{ 
    static BOOL initialized = NO; 
    if(!initialized) 
    { 
     initialized = YES; 
     instance = [[Universe alloc] init]; 
    } 
} 

- (id) init 
{ 
    self = [super init]; 
    if (self != nil) { 
     self.showHistory = YES; 
    } 
    return self; 
} 

ale teraz zdaję sobie sprawę, że chciałbym oznacz ją z interfejsu Builder. Myślałam tylko o cięcia w sposobie init jak tak

if (instance) 
     return instance; 

jest to zły pomysł? Wolałbym, aby IB podniósł instancję już utworzoną w metodzie +initialize.

Odpowiedz

6

Można to zrobić. Istnieje sekcja o tym w wzorach kakao przez Bucka i Yachtmana.

W twoim przypadku można zrobić coś wzdłuż linii:

static Universe *instance; 

+ (Universe *)instance { return instance; } 

+ (id)hiddenAlloc 
{ 
    return [super alloc]; 
} 

+ (id)alloc 
{ 
    return [[self instance] retain]; 
} 

+ (void)initialize 
{ 
    static BOOL initialized = NO; 
    if(!initialized) 
    { 
     initialized = YES; 
     instance = [[Universe hiddenAlloc] init]; 
    } 
} 

- (id)init 
{ 
    if(instance==nil) // allow only to be called once 
    { 
    // your normal initialization here 
    } 
    return self; 
} 

stalówki Kod ładowania będzie wtedy poprawnie odebrać singleton poprzez jego wywołanie [[Universe alloc] init] i nadal można używać instance w kodzie jako przed.

Książka zawiera więcej szczegółów i zaleca wdrożenie new i allocWithZone (oba po prostu jako return [self alloc];), plus odcinki błędach raportowania złapać copyWithZone i mutableCopyWithZone prób na dokładkę.

+1

Oto, co zrobiłem, aby wprowadzić wersja wtyczki kodu sieciowego klienta, który był pierwotnie w aplikacji Cocoa. Współpracownik chciał tego w wtyczce, więc poszedłem drogą singletonową, więc zawsze istniało tylko jedno rzeczywiste wystąpienie klienta sieciowego (wewnętrznie). – ExitToShell

+0

@Newariant, świetna odpowiedź, która sprawia, że ​​cieszę się, że zadałem to pytanie, a nie tylko odrzuciłem to jako głupie. –

+2

'+ alloc' powinno zwrócić' [[self instance] retain] ', ponieważ' alloc' zwraca posiadany obiekt. –

1

To przeciek. Możesz go uciec, jeśli zmienisz go na:

if(instance) { 
    [self release]; 
    return instance; 
} 

ale nadal trochę mnie pachnie. Jestem ciekawy, jaki użytek masz dla singletonów w IB; Podejrzewam, że uniknęłbym tej konstrukcji w moim kodzie.

+0

Cześć Seamus, tak, kod i tak nie działa z powodu "Ten koder wymaga, aby zwrócone obiekty zostały zwrócone z initWithCoder" ... w każdym razie idę do kasy Zewnętrzny obiekt w IB. Chodzi o to, że używam jednego centralnego Singletona jako pomostu do wszystkich elementów aplikacji ... więc każdy kawałek rejestruje się singletonem. Ale pomyślałem, dlaczego nie podłączyć niektórych? –

+0

http://stackoverflow.com/questions/350861/what-bad-practice-do-you-do-and-why/350900#350900 –

+1

^^ kochaj to spowiedź wątku :) –

Powiązane problemy