不能在属性初始化程序中使用实例成员,将变量设置为惰性不起作用

时间:2017-08-24 08:43:39

标签: ios swift nsuserdefaults

其他SO问题指出在变量之前使用lazy,但在这种情况下似乎不起作用。

我仍然会收到此错误,

  

不能在属性初始值设定项中使用实例成员'defaults';   属性初始化程序在'self'可用之前运行

我在哪里弄错了?

class UserData{

    let defaults        = UserDefaults.standard
    lazy var userDataDict    = defaults.object(forKey: "UserDataDict") as? [String: String] ?? [String: String]()


    static func setMobileNumber(mobileNumber: String){

        userDataDict["mobileNumber"]         =   mobileNumber

    }
}

1 个答案:

答案 0 :(得分:0)

试试这个语法:

lazy var userDataDict: [String : String] = { 
    defaults.object(forKey: "UserDataDict") as? [String: String] ?? [String: String]()
}()

但是,这只会设置userDataDict一次(第一次访问它),在此之后您将看不到对UserDefaults.standard所做的任何更改/更新

我建议您改为使用计算属性

var userDataDict: [String : String] { 
    guard let dict = defaults.object(forKey: "UserDataDict") as? [String: String] ?? [String: String]() else {
        return [:]
    }
    return dict
}

(无论如何,懒得只做一次这种代价高昂的操作)

另外,我认为将UserDefaults.standard的副本作为对象的属性并不重要;或许它最好有:

// remove: 
// let defaults = UserDefaults.standard

var userDataDict: [String : String] {
    guard let dict = UserDefaults.standard.object(forKey: "UserDataDict") as? [String: String] ?? [String: String]() else {
        return [:]
    }
    return dict
}

作为最后一个标志,就用户默认值数据库而言,所有这些都使您的字典“只读”;如果您希望保留任何更改,您的财产也需要 setter

var userDataDict: [String : String] {
    get {
        guard let dict = UserDefaults.standard.object(forKey: "UserDataDict") as? [String: String] ?? [String: String]() else {
        return [:]
        }
        return dict
    }
    set (newValue) {
        UserDefaults.standard.set(newValue, forKey: "UserDataDict")
        UserDefaults.standard.synchronize()
    }
}