一 alloc和allocWithZone
初始化一个对象的时候,[[Class alloc] init],其实是做了两件事。
- alloc 给对象分配内存空间
- init对对象初始化,包括设置成员变量初值这些工作。
而给对象分配空间,除了alloc方法之外,还有另一个方法: allocWithZone.
使用alloc方法初始化一个类的实例的时候,默认是调用了allocWithZone的方法。
二 ARC模式下实现单例模式
//首先定义一个全局静态变量,不让外界访问
static Tools *_instance;
//对外界提供一个友好的接口
+(instancetype)shareTools {
// 此处用self主要是考虑到如果有子类继承
return [[self alloc] init];
}
//重写关键方法
+(instancetype)allocWithZone:(struct _NSZone *)zone {
@synchronized(self) {
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
return _instance;
}
}
//严谨起见
-(id)copyWithZone:(NSZone *)zone {
return _instance;
}
-(id)mutableCopyWithZone:(NSZone *)zone {
return _instance;
}
补充:copy和mutableCopy方法
- mutableCopy 创建一个新的可变对象,并初始化为原对象的值,新对象的引用计数为 1;
- copy 返回一个不可变对象。分两种情况:
(1)若原对象是不可变对象,那么返回原对象,并将其引用计数加 1
(2) 若原对象是可变对象,那么创建一个新的不可变对象,并初始化为原对象的值,新对象的引用计数为 1。
单例还可以通过GCD的一次性函数实现
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;