单例模式
定义:确保一个类只有一个实例,并提供一个全局访问点
简单来说就是 一个类在程序运行期间只能生成一个实例
一、使用GCD实现单例
1、swift 3.0以前
使用GCD中的dispatch_once来创建单例对象
class SingletonManager {
static private var onceToken: dispatch_once_t = 0
static private var staticInstance: SingletonManager? = nil
static func sharedInstance() -> SingletonManager {
dispatch_once(&onceToken) {
staticInstance = SingletonManager()
}
return staticInstance!
}
private init() {}
}
测试
在swift3.0之前,可以使用 unsafeAddressOf 方式打印对象的内存地址
let singleton1 = SingletonManager.sharedInstance()
let singleton2 = SingletonManager.sharedInstance()
unsafeAddressOf(singleton1)
unsafeAddressOf(singleton2)
2、swift3.0以后
在swift3.0及以后,dispatch_once_t 及unsafeAddressOf 在swift3已经废弃。
如果仍想继续使用GCD的方法创建单例,需要对DispatchQueue进行扩展,实现dispatch_once的功能
1)对DispatchQueue进行扩展
//扩展DispatchQueue实现原有的功能
public extension DispatchQueue{
private static var _onceTracker = [String]()
public class func once(_ token : String, block:@noescape(Void)->Void){
objc_sync_enter(self)
defer{
objc_sync_exit(self)
}
if _onceTracker.contains(token) {
return
}
_onceTracker.append(token)
block()
}
}
2)创建单例
class SingletonManager{
private static let onceToken = NSUUID().uuidString
private static var staticInstance : SingletonManager? = nil
static func sharedInstance()->SingletonManager{
DispatchQueue.once(onceToken) {
staticInstance = SingletonManager()
}
return staticInstance!
}
private init() {}
}
3)创建获取内存地址的方法
//查看对象内存地址
func printAdress(_ values : AnyObject...){
for value in values {
print(Unmanaged.passUnretained(value).toOpaque())
}
}
4)测试
print("------GCD实现单例")
let singleton1 = SingletonManager.sharedInstance()
let singleton2 = SingletonManager.sharedInstance()
printAdress(singleton1 as AnyObject, singleton2 as AnyObject)
3、测试结果
GCD方式创建单例,测试的两个单例对象内存地址是同一个
二、使用静态私有常量和静态方法来实现单例
1、单例的创建
创建单例的步骤:
1、先创建一个私有静态常量并分配值
2、在静态方法中对其进行返回
3、使用:使用者调用sharedInstance()方法时,就会将staticInstance实例进行返回
注意:需要将该类的构造方法 即 init() 声明成私有方法,防止外部通过构造器来直接生成实例
class SingletonManager1{
private static let staticInstance : SingletonManager1 = SingletonManager1()
static func sharedInstance()->SingletonManager1{
return staticInstance
}
private init() {}
}
2、测试
通过声明两个单例对象,查看其内存地址是否一致,内存地址的打印同1中一致
let singleton3 = SingletonManager1.sharedInstance()
let singleton4 = SingletonManager1.sharedInstance()
printAdress(singleton3 as AnyObject, singleton4 as AnyObject)
单例对象的内存地址是同一个