Singleton aus 'Cocoa Design Patterns'

leftshift

leftshift

Mitglied
Thread Starter
Dabei seit
24.02.2009
Beiträge
45
Reaktionspunkte
6
Hallöchen,

ich arbeite gerade das obige Buch durch und hänge am Singleton fest. In C++/Java kein Problem aber in Objective-C?!

Hier ist mal die Implementierung:

Code:
@interface Singleton : NSObject 
{
@private
    int m_valueX;
}

+ (id)sharedInstance;
- (id)init;
- (int)valueX;

@end


#import "Singleton.h"


@implementation Singleton

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

+ (id)alloc
{
    return nil;
}

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


+ (id)allocWithZone:(NSZone *)zone
{
    return [self alloc];
}

- (id)copyWithZone: (NSZone*)zone
{
    NSLog(@"Singleton: attempt to -copy may be a bug.");
    [self retain];
    return self;
}

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


+ (Singleton*)sharedInstance
{
    static Singleton *theInstance = nil;
    
    if( !theInstance )
    {
        theInstance = [[[self class ] hiddenAlloc] init];
    }
    
    return theInstance;
}

- (id)init
{
    self = [super init];
    m_valueX = 99;
    
    return self;
}

- (int)valueX
{
    return m_valueX;
}

@end

Aufruf mit: [Singleton sharedInstance];

Er springt auch brav in die Methode 'hiddenAlloc' bekommt bei '[super alloc]' aber einen Nullpointer.
Hat einer diese Klasse lauffähig bekommen?

leftshift
 
Ich vermute mal, dass die Standardimplementierung von +alloc +allocWithZone aufruft. Die hast du aber überschrieben, also lass das. Das Überschreiben von +new kannst du dir übrigens sparen. Da kommt automatisch nil bei raus, wenn du alloc tötest.

Kritischer ist auch dein +sharedInstance. Das Teil ist nicht threadsicher. Implementiere sie lieber wie in http://mikeash.com/pyblog/friday-qa...d-central-dispatch-part-iv-odds-and-ends.html beschrieben so:

Code:
    + (id) sharedInstance
    {
        static dispatch_once_t pred;
        static Singleton *theInstance = nil;
        dispatch_once(&pred, ^{
            whatever = [[self hiddenAlloc] init];
        });
        return whatever;
    }

Init schreibt man i.d.R. übrigens auch anders http://stackoverflow.com/questions/...-should-i-check-if-self-super-init-is-not-nil

Anmerkung: Außerdem ist das [self class] doppelt gemoppelt. self ist an dieser Stelle schon die Klasse die du haben willst. +class ist in ObjC eine Identitätsfunktion also überflüssig an dieser Stelle.
 
Zuletzt bearbeitet:
Danke mal! Ich habe die Implementierung zu 90% aus dem Buch übernommen. In C++ benutze ich das 'double-checked locking' und habe sehr gute Erfahrungen damit gemacht. Hier habe ich auch noch eine Implementierung des Singleton patterns gefunden:
http://www.cocoadev.com/index.pl?SingletonDesignPattern

leftshift
 
Zurück
Oben Unten