如何在Swift中使用NSCoding和单例类

时间:2016-05-22 21:12:59

标签: ios swift

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

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

另一个问题是,将singleton用于用户对象是个好主意吗?

2 个答案:

答案 0 :(得分:0)

您需要做的是对单例模式实现的非正统方法。通常在swift中你这样做:

class MySingleton {
static let sharedInstance = MySingleton()
    init() {
       println("BBB")
    }
}

您无法以这种方式使用它,因为所有设置工作都延迟到初始化程序,而您希望在实际创建实例之前进行一些调整。执行所需操作并保持线程安全的最简单方法是使用来自apple C库深度的dispatch_once:

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!
    }
}

作为旁注 - 我通常做的是我使用Core Data对象来建模用户,因此可以通过持久性来节省很多痛苦。我将用户保留为某个单独类的字段,专用于保持一般应用程序状态,访问令牌等。类初始化程序从持久性中恢复用户对象并将其分配给它的字段。

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

答案 1 :(得分:-1)

咩。原则上,不,这可能是不好的形式,但在实践中我已经取得了非常好的成功,并且不得不在代码库中进行大规模的扭曲,我没有这样做。单身人士是可可的一个值得尊敬的部分。试图远离它们的是一个广泛的运动(包括我自己),但并不总是清楚疼痛是值得的。关于你是否应该或不应该在这里,我不会大声喧哗,让我们谈谈如何做。

答案是要记住可可单身人士不是单身人士。他们分享了单身人士。"他们只是一些例子。所以设定它。

struct User {
    static var sharedUser = User()
}

func decodeSomething() {
    User.sharedUser = ... some decoded user ...
}

这个表格不是线程安全的,可以没问题。如果您需要它是线程安全的,您可以通常的方式(dispatch_syncdispatch_barrier_async)执行此操作。如果要发布通知或以其他方式通知观察者用户已更改,您可以添加didSet处理程序。但这整个方法运作良好。

由于你有更多的经验,你可能会因为某些原因而决定你讨厌这个问题,因为你无法准确地表达出来,模糊地将其归结为可测试性" (我们很多人都这样做了),你会想出其他的解决方案。但实际上这很好。