一、在ARC环境下实现单例
1.创建一个单例类,假设类名为ClassName
2.在类的实现中,声明一个全局静态变量,确保该变量在整个程序运行时期内只会存在一份,且不会被外部修改。
static ClassName *_instance;
3.重写类的allocWithZone:
方法
- 可以通过懒加载的方式实现,不过为了确保线程安全,需要加上互斥锁,代码如下:
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
@synchronized (self) {
if (!_instance) {
_instance = [super allocWithZone:zone];
}
}
return _instance;
}```
- 也可以通过GCD一次性代码的方法实现,也可以确保线程安全,代码如下:
- (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
4.声明并实现一个工厂方法,方法最好以`shared`或`default`开头,返回单例的实例变量。
- (instancetype)sharedClassName {
return [[self alloc] init];
}
5.重写`copyWithZone:`和`mutableCopyWithZone:`方法,避免外部调用`copy`或`mutableCopy`时开辟新的储存空间。
- (id)copyWithZone:(NSZone *)zone {
return _instance;
} - (id)mutableCopyWithZone:(NSZone *)zone {
return _instance;
}
</br>
###二、在MRC环境下实现单例
在ARC的实现基础上,重写以下几个方法,废除掉单例的引用计数机制即可。
1.重写release方法,使调用release时什么都不做。
- (oneway void)release {
}
2.重写retain方法,使调用retain时不改变引用计数,仅返回实例变量。
- (instancetype)retain {
return _instance;
}
3.重写retainCount方法,返回一个最大的数,让调用者明白这是一个单例
- (NSUInteger)retainCount {
return MAXFLOAT;
}