333 Stimmen

Wie sollte mein Objective-C-Singleton aussehen?

Meine Singleton-Accessor-Methode ist normalerweise eine Variante von:

static MyClass *gInstance = NULL;

+ (MyClass *)instance
{
    @synchronized(self)
    {
        if (gInstance == NULL)
            gInstance = [[self alloc] init];
    }

    return(gInstance);
}

Was könnte ich tun, um dies zu verbessern?

2voto

lajos Punkte 25175

Dies funktioniert auch in einer Umgebung, in der kein Müll gesammelt wird.

@interface MySingleton : NSObject {
}

+(MySingleton *)sharedManager;

@end

@implementation MySingleton

static MySingleton *sharedMySingleton = nil;

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

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

-(void)dealloc {
    [super dealloc];
}

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

-(id)retain {
    return self;
}

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

-(void)release {
    //do nothing    
}

-(id)autorelease {
    return self;    
}

-(id)init {
    self = [super init];
    sharedMySingleton = self;

    //initialize here

    return self;
}

@end

2voto

CJ Hanson Punkte 813

Hier ist ein Makro die ich zusammengestellt habe:

http://github.com/cjhanson/Objective-C-Optimized-Singleton

Sie basiert auf die Arbeit hier von Matt Gallagher Aber eine Änderung der Implementierung zur Verwendung von Methode "Swizzling", wie hier von Dave MacLachlan von Google beschrieben .

Ich freue mich über Kommentare/Beiträge.

2voto

Jompe Punkte 21

Sollte dies nicht thread-sicher sein und das teure Sperren nach dem ersten Aufruf vermeiden?

+ (MySingleton*)sharedInstance
{
    if (sharedInstance == nil) {
        @synchronized(self) {
            if (sharedInstance == nil) {
                sharedInstance = [[MySingleton alloc] init];
            }
        }
    }
    return (MySingleton *)sharedInstance;
}

2voto

Fred McCann Punkte 21

Eine ausführliche Diskussion über das Singleton-Muster in Objective-C finden Sie hier:

Verwendung des Singleton-Musters in Objective-C

2voto

Tony Punkte 33555

Wie wäre es mit

static MyClass *gInstance = NULL;

+ (MyClass *)instance
{
    if (gInstance == NULL) {
        @synchronized(self)
        {
            if (gInstance == NULL)
                gInstance = [[self alloc] init];
        }
    }

    return(gInstance);
}

Sie vermeiden also die Synchronisierungskosten nach der Initialisierung?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X