Ios 如何在Swift中对单例类使用NSCoding

Ios 如何在Swift中对单例类使用NSCoding,ios,swift,Ios,Swift,对于iOS应用程序中的用户模型,我使用单例。 我想用NSCoding保存用户对象 保存它没有问题,但是如何将解码的用户分配给我的singleton的共享实例 还有一个问题,对用户对象使用单例是一个好主意吗。原则上,不,这可能是一种糟糕的形式,但在实践中,我用它取得了很好的成功,并且在代码库中进行了很大的扭曲,而我没有这样做。单身是可可的一部分。有一个广泛的运动(包括我自己)试图远离他们,但并不总是清楚这种痛苦是否值得。我不想对你是否应该在这里大吵大闹,让我们谈谈如何在这里 答案是要记住,可可单身

对于iOS应用程序中的用户模型,我使用单例。 我想用
NSCoding
保存用户对象

保存它没有问题,但是如何将解码的用户分配给我的singleton的共享实例


还有一个问题,对用户对象使用单例是一个好主意吗。原则上,不,这可能是一种糟糕的形式,但在实践中,我用它取得了很好的成功,并且在代码库中进行了很大的扭曲,而我没有这样做。单身是可可的一部分。有一个广泛的运动(包括我自己)试图远离他们,但并不总是清楚这种痛苦是否值得。我不想对你是否应该在这里大吵大闹,让我们谈谈如何在这里

答案是要记住,可可单身汉不是单身汉。他们是“共享单身”,只是一些例子。那就定下来吧

struct User {
    static var sharedUser = User()
}

func decodeSomething() {
    User.sharedUser = ... some decoded user ...
}
此表单不是线程安全的,这也可以。如果您需要它是线程安全的,您可以通过通常的方式(
dispatch\u sync
dispatch\u barrier\u async
)实现。如果要发布通知或以其他方式通知观察者用户已更改,则可以添加
didSet
处理程序。但整个方法都很有效


当你有更多的经验时,你可能会觉得你讨厌这个,因为你不能准确地表达,模糊地重复“可测试性”(我们中的许多人都这样做),你会想出其他的解决方案。但这真的很好。

Meh。原则上,不,这可能是一种糟糕的形式,但在实践中,我用它取得了很好的成功,并且在代码库中进行了很大的扭曲,而我没有这样做。单身是可可的一部分。有一个广泛的运动(包括我自己)试图远离他们,但并不总是清楚这种痛苦是否值得。我不想对你是否应该在这里大吵大闹,让我们谈谈如何在这里

答案是要记住,可可单身汉不是单身汉。他们是“共享单身”,只是一些例子。那就定下来吧

struct User {
    static var sharedUser = User()
}

func decodeSomething() {
    User.sharedUser = ... some decoded user ...
}
此表单不是线程安全的,这也可以。如果您需要它是线程安全的,您可以通过通常的方式(
dispatch\u sync
dispatch\u barrier\u async
)实现。如果要发布通知或以其他方式通知观察者用户已更改,则可以添加
didSet
处理程序。但整个方法都很有效


当你有更多的经验时,你可能会觉得你讨厌这个,因为你不能准确地表达,模糊地重复“可测试性”(我们中的许多人都这样做),你会想出其他的解决方案。但实际上这很好。

您需要做的是采用非正统的方法来实现单例模式。通常在swift中,您可以执行以下操作:

class MySingleton {
static let sharedInstance = MySingleton()
    init() {
       println("BBB")
    }
}
您不能以这种方式使用它,因为所有的设置工作都推迟到初始化器,而您希望在实际创建实例之前进行一些调整。要做您需要的事情并保持线程安全,最简单的方法是从apple的C库深处使用dispatch_一次:

class MySingleton : NSObject {
    class var sharedInstance: MySingleton {
        struct Statics {
            static var instance: MySingleton? = nil
            static var dispatchOnceToken: dispatch_once_t = 0
        }

        dispatch_once(&Statics.dispatchOnceToken) {
           if let data: NSData = .... (get your data here) {
               let decodedInstance = NSKeyedUnarchiver.unarchiveObjectWithData(data: data) as! MySingleton
           Statics.instance = decodedInstance
           } else {
              Statics.instance = MySingletion()
           }
        }
        return Statics.instance!
    }
}
作为旁注——我通常做的是,我使用核心数据对象为用户建模,因此用持久性为自己省去了很多痛苦。我将用户作为一个字段保存在某个单例类上,该类专用于保存一般应用程序状态、访问令牌等。类初始化器从持久性恢复用户对象,并将其分配给它的字段


最后但并非最不重要的一点是,在将任何单身人士引入应用程序之前,一定要三思而后行,因为这种模式很容易被滥用

您需要做的是对单例模式实现采用一种非正统的方法。通常在swift中,您可以执行以下操作:

class MySingleton {
static let sharedInstance = MySingleton()
    init() {
       println("BBB")
    }
}
您不能以这种方式使用它,因为所有的设置工作都推迟到初始化器,而您希望在实际创建实例之前进行一些调整。要做您需要的事情并保持线程安全,最简单的方法是从apple的C库深处使用dispatch_一次:

class MySingleton : NSObject {
    class var sharedInstance: MySingleton {
        struct Statics {
            static var instance: MySingleton? = nil
            static var dispatchOnceToken: dispatch_once_t = 0
        }

        dispatch_once(&Statics.dispatchOnceToken) {
           if let data: NSData = .... (get your data here) {
               let decodedInstance = NSKeyedUnarchiver.unarchiveObjectWithData(data: data) as! MySingleton
           Statics.instance = decodedInstance
           } else {
              Statics.instance = MySingletion()
           }
        }
        return Statics.instance!
    }
}
作为旁注——我通常做的是,我使用核心数据对象为用户建模,因此用持久性为自己省去了很多痛苦。我将用户作为一个字段保存在某个单例类上,该类专用于保存一般应用程序状态、访问令牌等。类初始化器从持久性恢复用户对象,并将其分配给它的字段


最后但并非最不重要的一点是,在将任何单身人士引入应用程序之前,一定要三思而后行,因为这种模式很容易被滥用

“将singleton用于用户对象是一个好主意吗?”这是一个意见和争论的问题(不鼓励堆栈溢出),但这里有很多关于这个主题的想法:“将singleton用于用户对象是一个好主意吗?”这是一个意见和争论的问题(不鼓励堆栈溢出),但这里有很多关于这个话题的想法: