只能生成一个实例的类是实现了Singleton模式的类型。由于设计模式在面向对象程序设计中起着举足轻重的作用,在常用的模式中,singleton是唯一一个能够用短短几十行代码完整实现的模式。
static PPLAccountManager *sharedInstance = nil;
1.最简单(非线程安全)
+ (PPLAccountManager*)sharedManager {
if (sharedInstance == nil ) {sharedInstance = [[self alloc]init];
}
return sharedInstance;
}
单线程下运行正常,但是在多线程下就有问题了。如果两个线程同时运行到判断shareInstance是否为nil的if语句,且shareInstance没有创建时候,那么2个线程都会创建一个实例,此时单例就不在满足单例模式的要求了。为了保证多线程环境下我们还是只能得到类型的一个实例,需要加上一个同步锁。如下:
2.线程安全(不是最优)
+ (PPLAccountManager*)sharedManager {
@synchronized ( self ){if (sharedInstance == nil) {
sharedInstance = [[selfalloc]init];
}
return sharedInstance;
}
}
这里还不是很完美。我们还是设想两个线程同时想创建一个实例,由于同一时刻只能有一个能得到同步锁,每当第一个线程锁加上锁,第二个线程只能等待,当第一个线程发现实例还没有创建时,它创建一个实例。接着第一个线程释放同步锁,此时第二个线程可以加上同步锁,并运行接下来的 代码。我们每次得到单例实例,都会试图加上一个线程锁,而加锁是一个非常耗时的操作,在没有必要的时候,我们尽量要避免。
3.线程安全(逻辑复杂)
+ (PPLAccountManager*)sharedManager {
if (sharedInstance == nil) {
@synchronized(self){
if (sharedInstance == nil) {
sharedInstance = [[self alloc]init];
}
}
}
return sharedInstance;
}
这里用了2个if判断来提高效率,但是代码实现逻辑比较复杂,容易出错,我们还有更加优秀的的解法。
4.最优算法(官方推荐)
+ (PPLAccountManager*)sharedManager {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedInstance = [[self alloc] init]; });
return sharedInstance;
}
}