方法一、(官方版)
这个方法为苹果公司官方的方法;
static id _sharedManager = nil;
+ (instancetype)defaultManager {
if (_sharedManager == nil) {
_sharedManager = [[super allocWithZone:NULL] init];
}
return _sharedManager;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
return [self sharedManager];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
解释:
[[Class alloc] init];
其实是做了两件事。 alloc 给对象分配内存空间,init是初始化对象,包括设置成员变量初值等。而给对象分配空间,除了alloc方法之外,还有另一个方法: + (instancetype)allocWithZone:
。
而使用alloc方法初始化一个类的实例的时候,默认调用了+ (instancetype)allocWithZone:
方法,所以创建单例覆盖这个方法也是必须的了。
方法二、(完整版)
//全局变量
static id _sharedManager = nil;
//单例方法
+(instancetype)shareManager{
return [[self alloc] init];
}
//初始化方法
- (instancetype)init{
// 只进行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedManager = [super init];
});
return _sharedManager;
}
//alloc会调用allocWithZone:
+(instancetype)allocWithZone:(struct _NSZone *)zone{
//只进行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedManager = [super allocWithZone:zone];
});
return _sharedManager;
}
//如果不刻意调用[object copy]�方法,下面的方法可以不使用
//copy会调用copyWithZone:
- (id)copyWithZone:(NSZone *)zone{
return _sharedManager;
}
+ (id)copyWithZone:(struct _NSZone *)zone{
return _sharedManager;
}
//mutableCopy会调用mutableCopyWithZone:
- (id)mutableCopyWithZone:(NSZone *)zone{
return _sharedManager;
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone{
return _sharedManager;
}
解释:
dispatch_once不仅意味着代码仅会被运行一次,而且还是线程安全的,这就意味着你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。
对象是可以被copy/mutableCopy的,为了让被copy的对象也是“唯一”的,需要覆盖copy/mutableCopy的方法(如果可以保证不使用copy方法可以忽略这些方法的覆盖)
方法三、(简易版)
确保项目中只使用[Class shareManager]
调用该类时可以用这个简易的方法。不能使用[[Class alloc] init];[object copy];
这些方法调用呦~
+ (instancetype)shareManager {
static ZingChatManager *_sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedManager = [[Class alloc] init];
});
return _sharedManager;
}