Swift单例写法

2018/10/30 posted in  iOS

介绍swift的单例类写法之前,可以先回顾一下oc中单例的写法如下。

//单例类
@interface Manger : NSObject
+ (instancetype)sharedManger;
@end

//然后.m文件里写实现
@implementation Manger
+ (instancetype)sharedManger {
    static Manger *sharedManger = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedManger = [self new];
    });
    return sharedManger;
}

swift单例写法

  • 简单写法
import UIKit
//仿OC写法
class Manger: NSObject {
    static let instance: Manger = Manger()
    class func shared() -> Manger {
        return instance
    }
}
//简便写法
class Manger {
    static let shared = Manger()
}

这样对比下来swift真的是极大的减少了代码量,所有也会有一些人推荐如果开发新项目,建议使用swift开发,毫无疑问。

另外swift 还有一种类似oc的写法如下。

  • 复杂写法
class Singleton {
    class var sharedInstance: Singleton {
        struct Static {
            static var oncetoken: String? = NSUUID().uuidString

            static var instance: Singleton? = nil
        }
        DispatchQueue.once(token: Static.oncetoken) {
            Static.instance = Singleton()

        }
        return Static.instance!
    }
}

extension DispatchQueue {
    private static var _onceTracker = [String]()
    public class func once(token: String, block: () -> ()) {
        objc_sync_enter(self)
        defer {
            objc_sync_exit(self)
        }
        if _onceTracker.contains(token) {
            return
        }
        _onceTracker.append(token)
        block()
    }
    
    func async(block: @escaping ()->()) {
        self.async(execute: block)
    }

    func after(time: DispatchTime, block: @escaping ()->()) {
        self.asyncAfter(deadline: time, execute: block)
    }
}

之所以写DispatchQueue的扩展是因为swift3中取消了dispatch_once_t的使用
'dispatch_once' is unavailable in Swift: Use lazily initialized globals instead

建议使用懒加载的初始化全局替代。

因为原来自从swift 1.x开始swift就已经开始用dispatch_one机制在后台支持线程安全的全局lazy初始化和静态属性.所以static var背后已经在使用dispatch_once了.