一、意图

保证一个类公有一个实例,并提供一个访问它的全局访问点。

二、使用场景

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下的实现,我们保证有且仅有一个实例,这种实现方式是错误的

Swift中Singleton的实现的更多相关文章

  1. 在Swift中实现单例方法

    在写Swift的单例方法之前可以温习一下Objective-C中单例的写法: + (instancetype)sharedSingleton{ static id instance; static d ...

  2. Swift中的单例的实现方式

    单例在iOS日常开发中是一个很常用的模式.对于希望在 app 的生命周期中只应该存在一个的对象,保证对象的唯一性的时候,一般都会使用单例来实现功能.在OC单例的写法如下: @implementatio ...

  3. swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明

    关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...

  4. 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON

    项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...

  5. Swift中的可选链与内存管理(干货系列)

    干货之前:补充一下可选链(optional chain) class A { var p: B? } class B { var p: C? } class C { func cm() -> S ...

  6. [翻译]理解Swift中的Optional

    原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...

  7. 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型

    有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...

  8. swift 中指针的使用UnsafeMutablePointer

    在swift中已经弱化了指针的使用,可以这么使用 let s: NSRange = NSMakeRange(, ) let at = UnsafeMutablePointer<NSRange&g ...

  9. swift 中数据类型那个的转换

    在swift中关于数据类型的转换,如果参数是可选类型? 那么打印或者转换的结果 会带有Optional 字样,,

随机推荐

  1. 【Codeforces Round #411 (Div. 1)】Codeforces 804C Ice cream coloring (DFS)

    传送门 分析 这道题做了好长时间,题意就很难理解. 我们注意到这句话Vertices which have the i-th (1 ≤ i ≤ m) type of ice cream form a ...

  2. hdoj1106

    果然...这种一条字符串的处理,还是不熟练,居然wa了四次--. 预处理预处理!!!!: 然后中间对条件的确定,标记的改变+预处理,不够严谨啊!!! #include<cstdio> #i ...

  3. “XXX.Index”不扩展类“System.Web.UI.Page”,因此此处不允许的问题

    “XXX.Index”不扩展类“System.Web.UI.Page”,因此此处不允许的问题 原因:设计页面继承的路径和后台.cs页面类的路径不一致造成的 看下图 这个是设计页面的样式 这个是后台cs ...

  4. Nginx的location配置概述【转】

    语法规则: location [=|~|~*|^~] /uri/ { … } = 开头表示精确匹配^~ 开头表示uri以某个常规字符串开头,理解为匹配url路径即可.nginx不对url做编码,因此请 ...

  5. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) D

    Description A tree is an undirected connected graph without cycles. The distance between two vertice ...

  6. Fast Bit Calculations LightOJ - 1032

    Fast Bit Calculations LightOJ - 1032 题意:求0到n的所有数的二进制表示中,"11"的总数量.(如果有连续的n(n>2)个1,记(n-1) ...

  7. 总结 - 常见的JavaScript兼容性问题

    添加事件的方法 (元素, 绑定的事件类型, 事件触发的方法) addHandler: function (element, type, handler) { if (element.addEventL ...

  8. iphone 开发Categories 、Extensions 区别 --转

    Category和Extension这两个概念,即便对于Java程序员,可能也会感到陌生.这是Objective C为程序员提供的两个强大的动态机制——简单地说,它们允许程序员为已有的对象添加新的方法 ...

  9. 496 Next Greater Element I 下一个更大元素 I

    给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值.nums1 中数字 x 的下一个更大 ...

  10. 动手实现 React-redux(三):connect 和 mapStateToProps

    我们来观察一下刚写下的这几个组件,可以轻易地发现它们有两个重大的问题: 有大量重复的逻辑:它们基本的逻辑都是,取出 context,取出里面的 store,然后用里面的状态设置自己的状态,这些代码逻辑 ...