zoukankan      html  css  js  c++  java
  • iOS——Swift开发中的单例设计模式(摘译,非原创)

    最近在开发一个小的应用,遇到了一些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方式平移过来)

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

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

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

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

  • 相关阅读:
    mui 时间选择器和上传图片
    css实现聊天气泡效果
    css总结 -使用display:inline-block,出现元素高度错位
    js DIV延时几秒后消失或显示代码
    js监听textarea 内容的变化,并计算内容的长度c
    生成git的SSH公钥
    IDEA中把普通的Java项目转换成gradle项目
    Idea中自动生成get,set,toString等方法
    IDEA中阿里P3C插件的安装与使用
    IDEA中SonarLint的安装与使用
  • 原文地址:https://www.cnblogs.com/lihaiyin/p/4274185.html
Copyright © 2011-2022 走看看