题目
设计一个类,我们只能生成该类的一个实例。
思考
只能生成一个实例的类,是实现了 Singleton(单例)模式的类型,是考查了设计模式相关的问题
不好的解法1:只适用于单线程环境
由于要求只能生成一个实例,因此必须把构造函数设为私有函数,以禁止他人创建实例。
解法1:可以定义一个静态的实例,在需要的时候创建该实例。
不好的解法2:虽然在多线程环境中能工作,但效率不高
解法1中,单线程虽然能工作,但是在多线程下就有问题:如果两个线程同时运行到判断 instantce 是否为 null 的 if 语句,并且 instantce 的确没有创建时,那么两个线程都会创建一个实例,此时就不满足单例模式的要求。
为了解决该问题,需要加上一个同步锁。
解法2:加一个同步锁
加锁是一个非常耗时的操作,在没有必要的情况下,应该尽量避免。
可行的解法:加同步锁前后两次判断实例是否已存在
只是在实例还没有创建之前需要加锁操作,以保证只有一个线程创建出实例。当实例创建出来后,就不需要执行加锁操作。
解法3:
伪代码
if(instance == null){
加锁{
if(instance == null){
instance = xxxx(); // 创建实例
}
}
}
通过2次 if 判断来提高效率。
但是代码实现较为复杂,易出错。
强烈推荐的解法1:利用静态构造函数
oc 语法中有一个函数能够确保只调用一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"只执行一次");
});
强烈推荐的解法2:实现按需创建实例
某些编程语言的一些函数的调用时机不是由程序员控制的,可能导致在编译时触发,而不是在真正调用时触发,所以,需要做到按需加载,不会过早创建实例,从而降低内存的使用效率。
考察点:
- 单例模式
- 基础语法的理解
- 多线程