Swift中Singleton的实现
一、意图
保证一个类公有一个实例,并提供一个访问它的全局访问点。
二、使用场景
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一个非常重要的区别:
有部分人可能想通过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下的实现,我们保证有且仅有一个实例,这种实现方式是错误的
Swift中Singleton的实现的更多相关文章
- 在Swift中实现单例方法
在写Swift的单例方法之前可以温习一下Objective-C中单例的写法: + (instancetype)sharedSingleton{ static id instance; static d ...
- Swift中的单例的实现方式
单例在iOS日常开发中是一个很常用的模式.对于希望在 app 的生命周期中只应该存在一个的对象,保证对象的唯一性的时候,一般都会使用单例来实现功能.在OC单例的写法如下: @implementatio ...
- swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明
关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...
- 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON
项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...
- Swift中的可选链与内存管理(干货系列)
干货之前:补充一下可选链(optional chain) class A { var p: B? } class B { var p: C? } class C { func cm() -> S ...
- [翻译]理解Swift中的Optional
原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...
- 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型
有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...
- swift 中指针的使用UnsafeMutablePointer
在swift中已经弱化了指针的使用,可以这么使用 let s: NSRange = NSMakeRange(, ) let at = UnsafeMutablePointer<NSRange&g ...
- swift 中数据类型那个的转换
在swift中关于数据类型的转换,如果参数是可选类型? 那么打印或者转换的结果 会带有Optional 字样,,
随机推荐
- python __builtins__ 函数
dir(__builtins__) 1.'abs', 对传入参数取绝对值 abs(x, /) Return the absolute value of the argument. >>&g ...
- 黑客攻防技术宝典web实战篇:攻击用户·其他技巧习题
猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 已知一项应用程序功能将一个查询字符串参数的内容插入到某个 HTTP 重定向的 Locati ...
- noip 2012 Day2 T2 借教室
一.暴力简述 甩链接.jpeg 首先我们不难看出,这道题————并不是一道多难的题,因为显然,第一眼看题目时便很容易地想到暴力如何打:枚举每一种订单,然后针对每一种订单,对区间内的每一天进行修改(做减 ...
- macOS 设置Root密码
用管理员帐号进入Terminal: 1) 输入:sudo passwd root ,回车: 2) 输入新的root密码: 3) 输入:su : 4) 输入新密码: 这样就进入到root帐号了.
- 跟我一起玩Win32开发(10):绘图(C)
今天我们来欣赏一下用于填充图形的函数,当然我不会逐个去介绍,因为我们参考MSDN直接套参数就可以了. SetDCBrushColor函数有必要扯一下,它的声明如下: COLORREF SetDCBru ...
- swiper.js插件的使用
swiper切换动画效果,需要先加载swiper.animate.min.js和animate.min.css. <!DOCTYPE html><html> <he ...
- Beautiful People SGU - 199 ZOJ - 2319
最长上升子序列O(n log n):http://www.cnblogs.com/hehe54321/p/cf-340d.html 题目:https://cn.vjudge.net/problem/Z ...
- 水题 Codeforces Round #299 (Div. 2) A. Tavas and Nafas
题目传送门 /* 很简单的水题,晚上累了,刷刷水题开心一下:) */ #include <bits/stdc++.h> using namespace std; ][] = {" ...
- Android 暗码表
转自: http://blog.csdn.net/jiangshide/article/details/8192834 不同手机厂商可能会隐藏或修改暗码,部份暗码要谨慎使用,因为可能令手机失去原有的功 ...
- 自動獲取外網IP并發郵件
問題: 公司有一Web系統需開放給香港Office公司查詢資料,但最近動態域名需實名認證, 因系統較小型,非公開大範圍使用,所以再認證一域名也沒多大必要, 所以想定時生成一封能查詢外網IP的郵件發送給 ...