一、单例模式 是什么?
是一种用于确保某个类型的对象在应用中只存在一个实例
的设计模式.。
二、单例模式 常用于解决什么问题?
-
用一种统一的方式来处理所有同类型的任务,如:
1. 用于合并应用层所有同类型行为(如打电话,打开短信等)的UIApplication 单例, 2. 一些下载行为类单例,播放类单例等工具类型单例。
-
封装共享资源,如:
共享性质的 centerModel 型单例,一个应用该对应一个用户 Model 单例等
三、单例模式 具有哪些特性?
- 唯一性
单例必须是该类型唯一的实例
- 不可取代性
单例不能被另一个对象所取代,即使是同类型的对象也不行
- 可获取性
单例必须能能够让需要使用它的组件获取到
四、单例 怎样实现
注意点:
在 swift 中,单例只能使用引用类型来实现,即只有class 才支持单例模式。因为swift 中的将结构体和其他值类型赋值给新变量时,默认的会进行复制操作。
1. Swift 1.2之前
- 移植 OC 的方法(Swift皮,Objective-C心)
class Singleton {
class var sharedInstance: Singleton {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: Singleton? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = Singleton()
}
return Static.instance!
}
}
- 结构体方法(新瓶装老酒)
class Singleton {
class var sharedInstance: Singleton {
struct Static {
static let instance = Singleton()
}
return Static.instance
}
}
1. Swift 1.2之后
- 全局常量式
private let instance = Singleton()
class Singleton {
class var sharedInstance: Singleton {
return instance
}
}
“全局变量(还有结构体和枚举体的静态成员)的Lazy初始化方法会在其被访问的时候调用一次。类似于调用'dispatch_once'以保证其初始化的原子性。这样就有了一种很酷的'单次调用'方式:只声明一个全局变量和私有的初始化方法即可。”--来自Apple's Swift Blog
2. 单行单例式 (官方推荐)
class Singleton {
static let sharedInstance = Singleton()
private init() {}
}
private init() {}
必须保证init方法的私有性,保证单例是真正唯一的,避免外部对象通过访问init方法创建单例类的其他实例。由于Swift中的所有对象都是由公共的初始化方法创建的,我们需要重写自己的init方法,并设置其为私有。如果你需要的是类似 defaultSingleton 的形式的单例 (也就是说这个类的使用者可以创建自己的实例) 的话,可以去掉这个私有的 init 方法。
static let
可以保证唯一性的原因:
在Swift 1.2以后,swift 有了访问权限设置(access control specifiers) 的功能和静态类成员(static class members)。这意味着我们终于可以摆脱混乱的全局变量、全局命名空间,也不会发生命名空间冲突了。
在初始化类变量的时候,Apple 将会把这个初始化包装在一次 swift_once_block_invoke 中,以保证它的唯一性。
Ref
Swift中编写单例的正确方式
Using a dispatch_once singleton model in Swift
单例
Other
private 关键字
Swift 具有访问级别的控制权限,我们可以在变量定义或方法前面加上 private 关键字,使这个变量或方法只在当前文件中可以被访问。static let sharedInstance
它是 swift 1.2 才具有的静态类成员功能代码实现方式。