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

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

 1 class var sharedInstance:TPScopeManager {
 2     get {
 3         struct Static {
 4             static var instance : TPScopeManager? = nil
 5         }
 6
 7         if !Static.instance {
 8             Static.instance = TPScopeManager()
 9         }
10
11         return Static.instance!
12     }
13 }

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

全局常量

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

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 = 0
            static var instance : Singleton? = nil
        }
        dispatch_once(&Static.onceToken) {
            Static.instance = Singleton()
        }
        return Static.instance!
    }
}

(原理一样,还是用struct支持类型变量这一优势,来把OC的dispatch_once方式平移过来,参考:http://www.codes51.com/article/detail_111374.html)

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

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

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

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. Android - 直线(line)画法

    Android - 直线(line)画法 本文地址: http://blog.csdn.net/caroline_wendy 横线(horizontal line) <View android: ...

  2. osx下一个MobileBackups简介

    自从开启了mac的TimeMachine之后,使用了一段时间的mac磁盘空间降低的非常多,于是使用du -d1(disk usage and depth is one)命令查看/文件夹空间的使用情况, ...

  3. Docker创建MySQL集装箱

    原文链接:Docker创建MySQL集装箱 这样做的目的是创建一个MySQL的image,出来的容器里自己主动启动MySQL服务接受外部连接 步骤: 1. 首先创建一个文件夹并在文件夹下创建一个Doc ...

  4. MySQL多实例配置(两)

    MySQL操作和维护一个集中的数据库的.它可以由一个单一的执行MySQL在数据库服务器,部署多MySQL示例.这个功能是由mysqld_multi实现.mysqld_multimysqld的服务进程. ...

  5. web前端利用HSTS(新的Web安全协议HTTP Strict Transport Security)漏洞的超级Cookie(HSTS Super Cookie)

    web前端如果想实现cookie跨站点,跨浏览器,清除浏览器cookie该cookie也不会被删除这似乎有点难,下面的教程让你完全摆脱document.cookie 1.服务器端设置HSTS 如PHP ...

  6. PHP邮件发送(转)

    php带有内置的mail() 发送邮件函数,但是较为繁琐:建议上网下载一个PHPMailer:

  7. 在CMD命令行和PowerShell中实现复制粘贴功能

    在CMD命令行和PowerShell中实现复制粘贴功能         常常使用命令行或者PowerShell的朋友肯定会遇到这样的情况:粘贴文本非常easy,右键--选择粘贴就可以,可是想要复制命令 ...

  8. HDU 1505 City Game(01矩阵 dp)

    Problem Description Bob is a strategy game programming specialist. In his new city building game the ...

  9. 看多csdn它还烂论坛?

    什么? 版权声明:本文博主原创文章,博客,未经同意不得转载.

  10. strtok、strtok_s、strtok_r 字符串切割函数

    1.strtok函数 函数原型:char * strtok (char *str, const char * delimiters); 參数:str,待切割的字符串(c-string):delimit ...