来源
单例模式的初衷是为了确保某些类的实例唯一,从而避免创建多个不必要的实例来节省资源、避免内存溢出。
特点
- 实例唯一
- 必须自身创建这个实例
- 向其他类提供使用这个实例的接口
方法
- 私有构造函数
- 创建私有静态实例
- 创建公有静态方法以获取私有实例
使用地方
根据单例模式的特点和基本方法可以知道,单例模式一般用于一些全局应用类、管理类和工具类,例如UIApplication、FileManager、Dao类等等。
常规用法
基本用法(饿汉式)
class SingleTon {
private init() {
}
private static let instance: SingleTon = SingleTon()
public static func getInstance() -> SingleTon {
return instance
}
}
这是单例模式最基本的用法,够用,唯一的缺点就是实例没调用就已经初始化了。
如果实例化的时候还需要设置一些属性的话,在swift中还可以用这样的闭包形式:
class SingleTon {
private init() {
}
private static let instance = {
//set
return SingleTon()
}()
public static func getInstance() -> SingleTon {
return instance
}
}
基本用法(懒汉式)
class SingleTon {
private init() {
}
private static var instance: SingleTon? = nil
public static func getInstance() -> SingleTon {
if instance == nil {
instance = SingleTon()
}
return instance!
}
}
懒汉式是为了弥补饿汉式没用就已经存在的缺点,需要才用。这很好,但是在多线程下是很不安全的。假如有两个线程同时访问,将会创建两个实例,显然是不符合多线程下的实例唯一。
经典用法(Double Check Lock)
class SingleTon {
private init() {
}
private static var instance: SingleTon? = nil
public static func getInstance() -> SingleTon {
if instance == nil {
objc_sync_enter(self)
if instance == nil {
instance = SingleTon()
}
objc_sync_exit(self)
}
return instance!
}
}
为了保持懒汉式的优点,需要才用,使用了实例判空。同时为了保证多线程下的实例单一,加入了同步机制和二次判空。这样即使多个线程同时访问,都能保证实例唯一。这是最常见的用法之一。
经典用法(内部静态类方法)
class SingleTon {
private init() {
}
public static func getInstance() -> SingleTon {
return SingleCreator.instance
}
class SingleCreator {
static let instance: SingleTon = SingleTon()
}
}
这种可以说是最得天独厚的,利用classloader机制保证实例化时只有一个线程,绝对线程安全。同时,又能最大限度节省资源,确保单例唯一。是最最常用的单例模式
后记
综上,无论任何语言最适合的还是DCL和静态类形式!
沉舟侧畔千帆过,病树前头万木春
且行且珍惜
网友评论