Ich weiß, dass es eine Menge Kommentare zu dieser "Frage" gibt, aber ich sehe nicht viele Leute, die vorschlagen, ein Makro zu verwenden, um das Singleton zu definieren. Es ist ein so gängiges Muster und ein Makro vereinfacht das Singleton erheblich.
Hier sind die Makros, die ich auf der Grundlage verschiedener Objc-Implementierungen, die ich gesehen habe, geschrieben habe.
Singeton.h
/**
@abstract Helps define the interface of a singleton.
@param TYPE The type of this singleton.
@param NAME The name of the singleton accessor. Must match the name used in the implementation.
@discussion
Typcially the NAME is something like 'sharedThing' where 'Thing' is the prefix-removed type name of the class.
*/
#define SingletonInterface(TYPE, NAME) \
+ (TYPE *)NAME;
/**
@abstract Helps define the implementation of a singleton.
@param TYPE The type of this singleton.
@param NAME The name of the singleton accessor. Must match the name used in the interface.
@discussion
Typcially the NAME is something like 'sharedThing' where 'Thing' is the prefix-removed type name of the class.
*/
#define SingletonImplementation(TYPE, NAME) \
static TYPE *__ ## NAME; \
\
\
+ (void)initialize \
{ \
static BOOL initialized = NO; \
if(!initialized) \
{ \
initialized = YES; \
__ ## NAME = [[TYPE alloc] init]; \
} \
} \
\
\
+ (TYPE *)NAME \
{ \
return __ ## NAME; \
}
Beispiel für die Verwendung:
MyManager.h
@interface MyManager
SingletonInterface(MyManager, sharedManager);
// ...
@end
MyManager.m
@implementation MyManager
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
SingletonImplementation(MyManager, sharedManager);
// ...
@end
Warum ein Schnittstellenmakro, wenn es fast leer ist? Code-Konsistenz zwischen den Header- und den Code-Dateien; Wartbarkeit für den Fall, dass Sie weitere automatische Methoden hinzufügen oder sie ändern möchten.
Ich verwende die Initialisierungsmethode, um das Singleton zu erstellen, wie in der beliebtesten Antwort hier (zum Zeitpunkt des Schreibens) verwendet wird.