保证一个类公有一个实例,并提供一个访问它的全局访问点。
1、使用场景
2、实现的重要三个步骤
Swift语言不支持变量及方法的权限,没有办法隐藏变量及方法,可以随意直接创建一个实例。单例的创建有很多写法,Swift支持只有struct支持静态变量,class不支持静态变量,所以很容易想到,在类的内部使用struct就能解决引用的保存问题,代码如下:
class SwiftSingleton {
class var shared: SwiftSingleton {
dispatch_once(&Inner.token) {
Inner.instance = SwiftSingleton()
}
return Inner.instance!
}
struct Inner {
static var instance: SwiftSingleton?
static var token: dispatch_once_t = 0
}
}
运行如下测试代码,进行简单测试: class SwiftSingletonTest: XCTestCase {
func testSingleton() {
let singleton1 = SwiftSingleton.shared
let singleton2 = SwiftSingleton.shared
assert(singleton1 === singleton2, "pass")
}
}
运行结果,左侧绿色对号代表执行通过: 其中===在Swift中代表“等价于”,比较的是两个变量或者常量的引用地址,只能用于class的比较
在Swift中static类型变量会自动实现成延迟加载模式,也可以更简单的实现成如下:
class SwiftSingleton {
class var shared: SwiftSingleton {
return Inner.instance
}
struct Inner {
static let instance = SwiftSingleton()
}
}
在所有语言中单例分为懒汉模式(延迟加载),饿汉模式,一般为了避免资源浪费,都喜欢实现成懒汉模式,即使用时在生成实例。在Swift语言中,由于static关键字做了优化,自动实现了 延迟加载模式,所以上面的代码实现的是懒汉模式而并非饿汉模式 class与struct一个非常重要的区别:
有部分人可能想通过struct来直接实现单例模式,由于struct传递时是传的值,会造成内存中有多个拷贝,测试如下:
struct SwiftSingleton {
var name: String = "1"
static let shared = SwiftSingleton()
}
var single1 = SwiftSingleton.shared
var single2 = SwiftSingleton.shared
single2.name = "2"
println("------->\(single1.name)")
println("------->\(single2.name)")
打印结果如下: ------->1
------->2
Program ended with exit code: 0
原文:http://www.cnblogs.com/motoyang/p/4858730.html