创建型模式-单例

2017-03-15  本文已影响26人  关灯侠

使用场景:只需要一个实例。例如现实世界的资源:服务器;或封装共享资源。

意义:

1、使得创建的实例始终保持一份,避免多次创建。
2、对象与现实资源对应。
3、封装共享资源。

创建Swift单例

1、使用全局常量

//全局变量
let globalLogger = Logger()

//final修饰后,防止子类创建
final class Logger{
    
    private var data = [String]()
    private let arrayQ = DispatchQueue.init(label: "arrayQ")
    //只在本文件有效,防止其他地方实例
    fileprivate init() { 
    }
    
    func log(msg:String){
        //同步添加数组
        arrayQ.sync {
            data.append(msg)
        }
    }
    
    func printLog(){
       for msg in data {
            print("Log:\(msg)")
        }
    }
}

2、使用结构体

final class BackupServer {
   //防止外界初始化
   fileprivate init(name:String) {
        self.name = name
        globalLogger.log(msg: "Created new server \(name)")
    }

    //BackupServer类型的属性server,初始化值是结构体的静态属性
    class var server:BackupServer{
        //结构体
        struct SingletonWrapper{
            //静态属性,用实例赋值
            static let singleton = BackupServer.init(name: "MainServer")
        }
        //返回结构体的属性值
        return SingletonWrapper.singleton
    }
}

使用注意:

1、Swift的单例模式只适用于引用类型,即类。结构体和其他值类型是不能用的,因为结构体本身具有复制功能。

2、处理并发。因为单例是共享资源,里面如果有数组、字典等集合,在读写操作的时候就需要考虑线程安全问题,避免出现多个线程同时写一个集合。Swift3的GCD需要适应一下。

  func log(msg:String){
        //同步添加数组
        arrayQ.sync {
            data.append(msg)
        }
    }
var arrayQ = DispatchQueue.init(label: "arrayQ")
func logItem(item:T) {
        //dispatch_barrier 最新写法
        //当barrier队列执行的时候,其他线程不能执行,就是串行队列
        //执行到其他队列的时候就是并行队列,直到运行到下一个barrier
        arrayQ.async(execute: DispatchWorkItem.init(qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier, block: { 
            self.dataItems.append(item.copy() as! T)
            self.callback(item)
        }))
    }

demo

例子都在这里

写在后面:

我写的关于设计模式内容,都是来自书《精通Swift设计模式》,如果有兴趣可以直接买来看看,不用看我的"歪曲理解"。我只是一个搬运工,记录过程,记录一点浅显的理解🙏。

上一篇 下一篇

猜你喜欢

热点阅读