• Swift辛格尔顿设计模式(SINGLETON)



    本文已更新为2.0语法,具体查看:一叶单例模式



    一、意图

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


    二、使用场景

    1、使用场景

    • 当类仅仅能有一个实例并且客户能够从一个众所周知的訪问点訪问它时
    • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。


    2、实现的重要三个步骤
    • 私有化构造方法(Swift不支持)
    • 使用一个静态变量保存实例的引用 
    • 提供一个全局的訪问方法

     三、 Swift语言下的实现

    Swift语言不支持变量及方法的权限,没有办法隐藏变量及方法,能够任意直接创建一个实例。

    单例的创建有非常多写法,Swift支持仅仅有struct支持静态变量。class不支持静态变量。所以非常easy想到,在类的内部使用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语言中,因为statickeyword做了优化。自己主动实现了 延迟载入模式。所以上面的代码实现的是懒汉模式而并不是饿汉模式


    四、可能引起错误的实现

    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下的实现,我们不能保证只有一个实例,这样的实现是一个问题

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    MySql 常用时间函数
    ORM执行原生SQL语句
    如何获取该变量(对象)是属于什么类型的
    预解析
    全局变量与局部变量
    函数可以作为参数使用,如果一个函数作为参数,那么我们说这个参数(函数)可以叫回调函数。
    函数的自调用,没有名字,声明的同时直接调用
    return之后的代码不执行
    js冒泡排序
    switch-case case后比较是严格模式
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4633957.html
Copyright © 2020-2023  润新知