Swift中Singleton的实现
2015-10-07 15:06
483 查看
一、意图
保证一个类公有一个实例,并提供一个访问它的全局访问点。二、使用场景
1、使用场景当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
2、实现的重要三个步骤
私有化构造方法(Swift不支持)
使用一个静态变量保存实例的引用
提供一个全局的访问方法
三、 Swift语言下的实现
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一个非常重要的区别: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
从上面可以看到,通过struct下的实现,我们保证有且仅有一个实例,这种实现方式是错误的
相关文章推荐
- 基于iOS开发对Swift构造方法的感悟
- Swift中的构造方法
- Swift详解之NSPredicate
- Swift学习笔记20——协议(Protocols)
- 【Swift】学习笔记(一)——熟知 基础数据类型,编码风格,元组,主张
- Swift与OC代码转换实例
- swift中的as?和as!
- Swift - 表格图片加载优化(拖动表格时不加载,停止时只加载当前页图片)
- Swift - 给图片添加滤镜效果(棕褐色老照片滤镜,黑白滤镜)
- Swift - .plist文件数据的读取和存储
- Swift - 使用HTML5进行iOS开发(将HTML5打包成iOS应用)
- Swift - 禁用UIWebView和WKWebView的下拉拖动效果
- Swift - 异步加载各网站的favicon图标,并在单元格中显示
- Swift - 使用闭包筛选过滤数据元素
- Swift - 使用UI Dynamics给UIKit组件添加移动吸附行为
- Swift - 使用UI Dynamics给UIKit组件添加重力和碰撞行为
- Swift - 重写UIKit框架类的init初始化方法(以UITabBarController为例)
- Swift - 如何实现字符串的HMAC_SHA1加密
- Swift - 获取字符串的MD5值
- Swift - iOS中各种视图控制器(View Controller)的介绍