若是您能够定位iOS 4.0或更高版本 安全
使用GCD,这是在Objective-C(线程安全)中建立单例的最佳方法吗? ide
+ (instancetype)sharedInstance { static dispatch_once_t once; static id sharedInstance; dispatch_once(&once, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; }
您能够经过覆盖alloc方法避免分配类。 spa
@implementation MyClass static BOOL useinside = NO; static id _sharedObject = nil; +(id) alloc { if (!useinside) { @throw [NSException exceptionWithName:@"Singleton Vialotaion" reason:@"You are violating the singleton class usage. Please call +sharedInstance method" userInfo:nil]; } else { return [super alloc]; } } +(id)sharedInstance { static dispatch_once_t p = 0; dispatch_once(&p, ^{ useinside = YES; _sharedObject = [[MyClass alloc] init]; useinside = NO; }); // returns the same object each time return _sharedObject; }
instancetype
只是Objective-C
的许多语言扩展之一,每一个新发行版都添加了更多扩展。 线程
知道,爱它。 code
并以它为例,说明如何关注底层细节能够使您洞悉转换Objective-C的强大新方法。 orm
+ (instancetype)sharedInstance { static dispatch_once_t once; static id sharedInstance; dispatch_once(&once, ^ { sharedInstance = [self new]; }); return sharedInstance; }
+ (Class*)sharedInstance { static dispatch_once_t once; static Class *sharedInstance; dispatch_once(&once, ^ { sharedInstance = [self new]; }); return sharedInstance; }
MySingleton.h get
@interface MySingleton : NSObject +(instancetype)sharedInstance; +(instancetype)alloc __attribute__((unavailable("alloc not available, call sharedInstance instead"))); -(instancetype)init __attribute__((unavailable("init not available, call sharedInstance instead"))); +(instancetype)new __attribute__((unavailable("new not available, call sharedInstance instead"))); -(instancetype)copy __attribute__((unavailable("copy not available, call sharedInstance instead"))); @end
MySingleton.m 博客
@implementation MySingleton +(instancetype)sharedInstance { static dispatch_once_t pred; static id shared = nil; dispatch_once(&pred, ^{ shared = [[super alloc] initUniqueInstance]; }); return shared; } -(instancetype)initUniqueInstance { return [super init]; } @end
若是要确保[[MyClass alloc] init]返回与sharedInstance相同的对象(我认为这不是必需的,可是有些人想要),则能够使用第二个dispatch_once轻松,安全地完成此操做: it
- (instancetype)init { static dispatch_once_t once; static Class *sharedInstance; dispatch_once(&once, ^ { // Your normal init code goes here. sharedInstance = self; }); return sharedInstance; }
这容许[[MyClass alloc] init]和[MyClass sharedInstance]的任何组合返回相同的对象。 [MyClass sharedInstance]会更有效率。 工做原理:[MyClass sharedInstance]将调用一次[[MyClass alloc] init]。 其余代码也能够屡次调用它。 初始化的第一个调用者将执行“常规”初始化,并将单例对象存储在init方法中。 之后对init的任何调用都将彻底忽略返回的alloc并返回相同的sharedInstance; alloc的结果将被释放。
+ sharedInstance方法将一如既往地工做。 若是不是第一个调用[[MyClass alloc] init]的调用者,则init的结果不是alloc调用的结果,可是能够。
要建立线程安全单例,您能够执行如下操做:
@interface SomeManager : NSObject + (id)sharedManager; @end /* thread safe */ @implementation SomeManager static id sharedManager = nil; + (void)initialize { if (self == [SomeManager class]) { sharedManager = [[self alloc] init]; } } + (id)sharedManager { return sharedManager; } @end
这个博客很好地解释了objc / cocoa中的单例