最近在开发一个小的应用,遇到了一些Objective-c上面常用的单例模式,但是swift上面还是有一定区别的,反复倒来倒去发现不能按常理(正常的oc to swift的方式)出牌,因此搜索了一些帖子。可能是xcode或者sdk的问题吧(我相信他们不会把未经测试的代码展示,吧?。。。),一些帖子中的代码犯了明显的错误,编译失败。于是有了这篇文章,分享给大家。

原作者实现了一种单例,但是红色代码导致非线程安全

 class var sharedInstance:TPScopeManager {
get {
struct Static {
static var instance : TPScopeManager? = nil
} 7 if !Static.instance {
8 Static.instance = TPScopeManager()
9 } return Static.instance!
}
}

于是有了下面这些解决方案(个人感觉很精彩):

全局常量

第一种:直接声明全局变量

let _SingletonSharedInstance = Singleton()

class Singleton  {
...
}

优点:代码最简洁。

缺点:代码开放度较乱

第二种就弥补了上面的缺点

private let _SingletonSharedInstance = Singleton()

class Singleton  {
class var sharedInstance : Singleton {
return _SingletonSharedInstance
}
}

注:因为不支持类型常量(即类的静态常量),所以这里使用了全局常量

这种方式支持延迟(lasy)初始化,因为Swift会延迟初始化全局常量(和变量),并且let关键字是线程安全的。(言外之意:全局变量也是延迟初始化的,但非线程安全?我表示不确定,请大神赐教)

Nested struct(估且译为内部struct吧)

class Singleton {
class var sharedInstance : Singleton {
struct Static {
static let instance : Singleton = Singleton()
}
return Static.instance
}
}

类不支持类型常量(即类的静态常量),但struct支持。利用此,可以达到类似的效果。

原著建议使用内部struct的方式,除非新版本中支持了类型变量

dispatch_once(这个真不能翻译)

传统的OC方式在Swift中也是支持的,对比上一种方式,这种方式很明显没有任何优势,但是还是写出来吧

class Singleton {
class var sharedInstance : Singleton {
struct Static {
static var onceToken : dispatch_once_t =
static var instance : Singleton? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = Singleton()
}
return Static.instance!
}
}

(原理一样,还是用struct支持类型变量这一优势,来把OC的dispatch_once方式平移过来)

如上所述,苹果官方已经明确声明延迟初始化是线程安全的,所以,没有必要再加一层dispatch_once或者类似的保护措施。

全局变量(struct和enum内部的静态成员也同样)的延迟加载本质是dispatch_once,因此如果想使用dispatch_once,不如直接声明一个私有全局变量,即保证了线程安全,也不会使代码过于open

我比较喜欢全局变量方式(当然是经过优化的那种),不用嵌套一层struct,比较简洁。大家喜欢哪种呢?

英语好的可以直接看原帖 http://stackoverflow.com/questions/24024549/dispatch-once-singleton-model-in-swift

iOS——Swift开发中的单例设计模式(摘译,非原创)的更多相关文章

  1. iOS--Swift开发中的单例设计模式

    最近在开发一个小的应用,遇到了一些Objective-c上面常用的单例模式,但是swift上面还是有一定区别的,反复倒来倒去发现不能按常理(正常的oc to swift的方式)出牌,因此搜索了一些帖子 ...

  2. IOS中的单例设计模式

    单例设计模式是IOS开发中一种很重要很常用的一种设计模式.它的设计原理是无论请求多少次,始终返回一个实例,也就是一个类只有一个实例.下面是苹果官方文档中关于单例模式的图片: 如图所示,左边的图是默认的 ...

  3. iOS 开发中的单例

    在iOS开发中经常会用到单例,比如每个iOS程序本身就是一个单例,在比如进行个人偏好设置存储的时候用的也是一个单例.那我们如何自己来写一个单例类呢,用自己的单例对象呢?下面是我写的一个单例的头文件里的 ...

  4. iOS 中的单例设计模式

    单例设计模式:在它的核心结构中只包含一个被称为单例类的特殊类.例如文件管理中的NSUserDefault,应用程序中的UIApplication,整个应用程序就这一个单例类,负责应用程序的一些操作,单 ...

  5. OC中的单例设计模式及单例的宏抽取

    // 在一个对象需要重复使用,并且很频繁时,可以对对象使用单例设计模式 // 单例的设计其实就是多alloc内部的allocWithZone下手,重写该方法 #pragma Person.h文件 #i ...

  6. Java中常用来处理时间的三个类:Date、Calendar、SimpleDateFormate,以及Java中的单例设计模式:懒汉式、饿汉式以及静态内部类式

    (一)java.util.Date类 1.该类有一个long类型的属性:用来存放时间,是用毫秒数的形式表示,开始的日期是从1970年1月1号 00:00:00.    2.该类的很多方法都已经过时,不 ...

  7. Python中的单例设计模式

    1)设计模式: 是前人工作的总结和提炼.通常,被人们广泛流传的设计模式.     某一问题的特定解决方案,使用设计模式是为了可重用代码,是代码更容易被人理解, 增加代码的可用性. 2)单例设计模式: ...

  8. java中的单例设计模式

    单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例. 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供 ...

  9. JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

    JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...

随机推荐

  1. UVM Top Testbench

    top testbench在top_tb中包含进所有的文件,将DUT放在top_tb中(例化DUT),连接好各个端口,提供clk时钟和rst_n复位信号.最主要的是要给组件中的虚接口设置接口,一般是给 ...

  2. node.js入门及express.js框架

    node.js介绍 javascript原本只是用来处理前端,Node使得javascript编写服务端程序成为可能.于是前端开发者也可以借此轻松进入后端开发领域.Node是基于Google的V8引擎 ...

  3. hivepython 同时读入python 且python脚本中处理外部文件txt

      找出表test_gid2中每个gid的安装列表中含有文件pkgs中的pkg名字的数据行. pkgs文件要与python脚本放在一个路径下. 用 transform 的传入数据的时候,不管原文件分隔 ...

  4. firefox广告拦截插件

    firefox广告拦截插件: Adblock Plus  Adblock Edge Adblock Plus Pop-up Addon 如果不能更新,则需要修改HOST: 117.18.232.191 ...

  5. IE调试网页之四:F12 开发人员工具控制台错误消息 (Windows)(转载)

    F12 工具控制台可以报告在运行时期间发生的错误和信息消息.本文将介绍错误消息,并提供有关如何修正这些错误的建议. 简介 F12 工具控制台错误消息提供了一些代码(例如,SEC7111 或 HTML1 ...

  6. max10中对DDR数据的采样转换

    (1)发现IP是这样处理DDR的数据:上长沿采的数据放在低位,下降沿采的数据在高位 (2)对于视频的行场信号是在下降沿采集,再延时一拍才能与数据对齐.

  7. iOS真机调试问题-App installation failed,The maximum number of apps for free development profiles has been reached.

    The maximum number of apps for free development profiles has been reached. 源引:http://www.jianshu.com ...

  8. Activity生命周期(二)

    ------siwuxie95 在项目 ActivityLifeCircle 的 MainActivity.java 中添加方法: onCreate()  onStart()  onResume()  ...

  9. CommandArgument传多个参数

    CommandArgument='<%#Eval("id")+","+Eval("interName") %>'

  10. 对比poj3050

    #include <stdio.h> const int MAXN = 10; const int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, ...