如何正确实现ARC兼容和`alloc init`安全的Singleton类?

我看到线程安全的版本

+(MyClass *)singleton { static dispatch_once_t pred; static MyClass *shared = nil; dispatch_once(&pred, ^{ shared = [[MyClass alloc] init]; }); return shared; } 

但是如果有人只是调用[MyClass alloc] init]会发生什么? 如何使其返回与+(MyClass *)singleton方法相同的实例?

苹果推荐严格的单例实现(不允许有其他types相同的活动对象):

 + (instancetype)singleton { static id singletonInstance = nil; if (!singletonInstance) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ singletonInstance = [[super allocWithZone:NULL] init]; }); } return singletonInstance; } + (id)allocWithZone:(NSZone *)zone { return [self singleton]; } - (id)copyWithZone:(NSZone *)zone { return self; } 

链接到苹果文档(页面底部,没有ARC)

这可能会有帮助,

 static Foo *sharedInstance = nil; + (Foo *)sharedInstance { if (sharedInstance == nil) { sharedInstance = [[super allocWithZone:NULL] init]; } return sharedInstance; } + (id)allocWithZone:(NSZone *)zone { @synchronized(self) { if (sharedInstance == nil) { sharedInstance = [super allocWithZone:zone]; return sharedInstance; } } return nil; } 

我拿起这个代码示例从下面的博客: http ://www.duckrowing.com/2011/11/09/using-the-singleton-pattern-in-objective-c-part-2/

在.h我们有

 @interface Foo : NSObject + (Foo *) sharedFoo; @end 

在我们有

 static SLFoo *sharedInstance = nil; static dispatch_queue_t serialQueue; @implementation Foo - (id)init { id __block obj; dispatch_sync(serialQueue, ^{ obj = [super init]; if (obj) { ; } }); self = obj; return self; } + (Foo *) sharedFoo; { static dispatch_once_t onceQueue; dispatch_once(&onceQueue, ^{ if (sharedInstance) { return; } sharedInstance = [[Foo alloc]init]; }); return sharedInstance; } + (id)allocWithZone:(NSZone *)zone { static dispatch_once_t onceQueue; dispatch_once(&onceQueue, ^{ serialQueue = dispatch_queue_create("com.mydomain.myApp.SerialQueueFoo", NULL); if (sharedInstance == nil) { sharedInstance = [super allocWithZone:zone]; } }); return sharedInstance; } @end 

注意allocWithZone。