以下是我实现单例类的两个方案,并且每个方案都经过了性能优化,如下:
方案1:互斥锁
通过互斥锁实现的单列代码;不保证只初始化一次!
//此单例方案不能保证只初始一次
//单例指针
static id _instance = nil;
+ (instancetype)sharedInstance
{
if (_instance == nil) { //因为加锁操作要比普通操作耗费更多的资源,所以尽量把锁内的执行条件在加锁之前先判断一次,以减少不必根的加锁操作
@synchronized(self) {
if (_instance == nil) {
_instance = [[self alloc] init];
}
}
}
return _instance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
if (_instance == nil) { //因为加锁操作要比普通操作耗费更多的资源,所以尽量把锁内的执行条件在加锁之前先判断一次,以减少不必根的加锁操作
@synchronized(self) {
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
}
}
return _instance;
}
//copy在底层 会调用copyWithZone:
-(id)copyWithZone:(NSZone*)zone {
return _instance;
}
+(id)copyWithZone:(struct _NSZone *)zone {
return _instance;
}
//mutableCopy在底层 会调用mutableCopyWithZone:
-(id)mutableCopyWithZone:(NSZone*)zone {
return _instance;
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone{
return _instance;
}
方案2:GCD
通过GCD方式实现的单列代码
//单列指针
static id _instance = nil;
//获取共享单列
+(instancetype)sharedInstance {
return [[self alloc] init];
}
//alloc方法会调用allocWithZone
+(instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//只执行一次
_instance = [super allocWithZone: zone];
});
return _instance;
}
//初始化方法
-(instancetype)init {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//只执行一次
_instance = [super init];
});
return _instance;
}
//copy在底层 会调用copyWithZone:
-(id)copyWithZone:(NSZone*)zone {
return _instance;
}
+(id)copyWithZone:(struct _NSZone *)zone {
return _instance;
}
//mutableCopy在底层 会调用mutableCopyWithZone:
-(id)mutableCopyWithZone:(NSZone*)zone {
return _instance;
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone{
return _instance;
}