我正在努力制定一个合适的单例模型用于Swift的使用。到目前为止,我已经能够得到一个非线程安全的模型工作为:

class var sharedInstance: TPScopeManager {
    get {
        struct Static {
            static var instance: TPScopeManager? = nil
        }

        if !Static.instance {
            Static.instance = TPScopeManager()
        }

        return Static.instance!
    }
}

将单例实例包装在Static结构中应该允许单个实例不与单例实例发生冲突,而不需要复杂的命名方案,并且它应该使事情相当私密。但是,这个模型显然不是线程安全的。所以我尝试将dispatch_once添加到整个事情中:

class var sharedInstance: TPScopeManager {
    get {
        struct Static {
            static var instance: TPScopeManager? = nil
            static var token: dispatch_once_t = 0
        }

        dispatch_once(Static.token) { Static.instance = TPScopeManager() }

        return Static.instance!
    }
}

但是我在dispatch_once行上得到了一个编译器错误:

不能将表达式的类型“Void”转换为类型“()”

我尝试了几种不同的语法变体,但它们似乎都有相同的结果:

dispatch_once(Static.token, { Static.instance = TPScopeManager() })

在Swift中dispatch_once的正确用法是什么?我最初认为问题出在错误消息中的()块上,但我看得越多,就越觉得可能是正确定义dispatch_once_t的问题。


当前回答

在Swift 1.2以上版本中,最好的方法是单行单例,如-

class Shared: NSObject {

    static let sharedInstance = Shared()

    private override init() { }
}

要了解更多关于这种方法的细节,请访问这个链接。

其他回答

   func init() -> ClassA {
    struct Static {
        static var onceToken : dispatch_once_t = 0
        static var instance : ClassA? = nil
    }

    dispatch_once(&Static.onceToken) {
        Static.instance = ClassA()
    }

    return Static.instance!
}

这是具有线程安全功能的最简单的一个。即使其他线程想要访问同一个单例对象,它们也不能访问。斯威夫特3/4

struct DataService {

    private static var _instance : DataService?

    private init() {}   //cannot initialise from outer class

    public static var instance : DataService {
        get {
            if _instance == nil {
                DispatchQueue.global().sync(flags: .barrier) {
                    if _instance == nil {
                        _instance = DataService()
                    }
                }
            }
            return _instance!
        }
    }
}

我更喜欢这样的实现:

class APIClient {

}

var sharedAPIClient: APIClient = {
    return APIClient()
}()

extension APIClient {
    class func sharedClient() -> APIClient {
        return sharedAPIClient
    }
}

我的实现方式在Swift…

ConfigurationManager.swift

import Foundation

    let ConfigurationManagerSharedInstance = ConfigurationManager()
 class ConfigurationManager : NSObject {
    var globalDic: NSMutableDictionary = NSMutableDictionary()

class var sharedInstance:ConfigurationManager {
    return ConfigurationManagerSharedInstance

}

init() {

    super.init()

    println ("Config Init been Initiated, this will be called only onece irrespective of many calls")   

}

从应用程序的任何屏幕访问globalDic。

读:

 println(ConfigurationManager.sharedInstance.globalDic)  

写:

 ConfigurationManager.sharedInstance.globalDic = tmpDic // tmpDict is any value that to be shared among the application

我建议使用枚举,就像您在Java中使用的那样,例如。

enum SharedTPScopeManager: TPScopeManager {
    case Singleton
}