我的单例访问方法通常是一些变种:
static MyClass *gInstance = NULL;
+ (MyClass *)instance
{
@synchronized(self)
{
if (gInstance == NULL)
gInstance = [[self alloc] init];
}
return(gInstance);
}
我能做些什么来改善这一点呢?
我的单例访问方法通常是一些变种:
static MyClass *gInstance = NULL;
+ (MyClass *)instance
{
@synchronized(self)
{
if (gInstance == NULL)
gInstance = [[self alloc] init];
}
return(gInstance);
}
我能做些什么来改善这一点呢?
当前回答
关于Objective-C中单例模式的深入讨论,请看这里:
在Objective-C中使用单例模式
其他回答
KLSingleton是: 可子类化(到n阶) 弧相容 使用alloc和init是安全的 装载 线程安全的 无锁(使用+initialize,而不是@synchronize) Macro-free Swizzle-free 简单的
克林格尔顿
我通常使用的代码大致类似于Ben Hoffstein的回答(这也是我从维基百科上得到的)。我使用它的原因是Chris Hanson在他的评论中提到的。
然而,有时我需要将一个单例放入NIB中,在这种情况下,我使用以下方法:
@implementation Singleton
static Singleton *singleton = nil;
- (id)init {
static BOOL initialized = NO;
if (!initialized) {
self = [super init];
singleton = self;
initialized = YES;
}
return self;
}
+ (id)allocWithZone:(NSZone*)zone {
@synchronized (self) {
if (!singleton)
singleton = [super allocWithZone:zone];
}
return singleton;
}
+ (Singleton*)sharedSingleton {
if (!singleton)
[[Singleton alloc] init];
return singleton;
}
@end
我把-retain(等等)的实现留给读者,尽管在垃圾收集环境中您只需要上面的代码。
这不应该是线程安全的,避免第一次调用后昂贵的锁定吗?
+ (MySingleton*)sharedInstance
{
if (sharedInstance == nil) {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[MySingleton alloc] init];
}
}
}
return (MySingleton *)sharedInstance;
}
简单回答:太棒了。
长话短说:类似....
static SomeSingleton *instance = NULL;
@implementation SomeSingleton
+ (id) instance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (instance == NULL){
instance = [[super allocWithZone:NULL] init];
}
});
return instance;
}
+ (id) allocWithZone:(NSZone *)paramZone {
return [[self instance] retain];
}
- (id) copyWithZone:(NSZone *)paramZone {
return self;
}
- (id) autorelease {
return self;
}
- (NSUInteger) retainCount {
return NSUIntegerMax;
}
- (id) retain {
return self;
}
@end
一定要阅读dispatch/once.h头文件以了解发生了什么。在这种情况下,标题注释比文档或手册页更适用。
关于单例宏代码的详细解释在Cocoa With Love博客上
http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html。