单例模式:确保一个类只有一个实例,并且提供一个全局的访问点。
单例模式是创建型模式之一。这也应该是最简单的一个设计模式。单例模式会创建一个全局的公有的对象,用来管理共享资源。
单例模式需要考虑多线程问题,如果我们多个线程同时创建单例,那么仍有可能会生成多个实例对象。
那怎么办? 大家做开发的应该都见过了同步锁,Java中的synchronized , iOS中是@synchronized 添加同步锁后能保证每次只创建一个对象。
这种每次都加载同步锁的情况是否会有其他问题? 性能!据我所致iOS中的同步锁在所有锁中性能最差。因此在不必要的情况下尽量不要用同步锁。
在java中可以在静态初始化器中创建单例。这样可以避免每次都使用同步锁。
iOS系统提供了GCD,GCD中有可以保持只执行一次代码的dispatch_once()方法,dispach_once是线程安全的,并且性能比@synchronized好很多,并且更轻量级。
在java中还有一种解决方式,即采用volatile关键字和synchronized来保证只创建一次单例模式。这种方式性能会大大的提高。
volatile关键字保证了内存可见性,但是volatile只有在java5之后才有效。如果要适配java5以下的版本,不能使用这种方式。
java双重检查加锁的单例
public class Singleton {
private volatile static Singleton instance;
private Singleton(){};
public static Singleton getInstance() {
if(instance == null) {
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
iOS dispatch_once的单例
#import "Singleton.h"
@implementation Singleton
+(instancetype)getInstance {
static Singleton * instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[Singleton alloc] init];
});
return instance;
}
@end
单例的优点
1.对象单一,不会出现多个对象节省内存空间
2.避免了重复创建/销毁对象,提高性能
3.避免了对共享资源的多重占用
4.为整个系统提供了一个访问点
单例模式的缺点
1.不适用于频繁变化的对象
2.单例模式被创建之后便不会被销毁,会一直占用系统内存。