1. 定义一个静态的实例成员=>保证对象在内存中只有一个副本,而且是保存在静态区的
static id instance;
2. 提供一个全局的访问方法,都以 shared + 类名 格式定义
+ (instancetype)sharedSoundTools;
3. 重写 allocWithZone 方法,=> 保证对象只被实例化一次,只分配一次内存空间
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [super allocWithZone:zone];
});
return instance;
4. 实现 shared 方法 => 保证对象只被 init(初始化) 一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
面试中,只需要写以上四个步骤就行!关于 gcd 部分,只需要写 dispatch_once 就可以
static id instance;
// alloc方法会调用 allocWithZone 方法
// 既然所有的内存分配最终都是 allocWithZone 来实现的
// 如果能够保证只实例化一个对象的副本
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
// 问题:如果是多线程运行!
// 目标:要保证 super allocWithZone 方法只执行一次!
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [super allocWithZone:zone];
});
return instance;
}
+ (instancetype)sharedSoundTools {
// 问题:如果直接返回 instance 会怎样?
// 如果第一次就调用类方法,因为没有实例化,会直接返回 nil
// return instance;
// 要保证单例对象只被 init(初始化) 一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
// 对象方法,说明拷贝的源已经存在 => instance 就一定已经被实例化过!
- (id)copyWithZone:(NSZone *)zone {
// id s = [[self.class allocWithZone:zone] init];
//
// return s;
return instance;
}