Swift:使用@propertyWrapper和[String:布尔值]

trnvg8h3  于 2023-01-19  发布在  Swift
关注(0)|答案(1)|浏览(103)

我使用以下属性 Package 器来存储值:

@propertyWrapper struct UserDefault<T: Codable> {
    var key: String
    var wrappedValue: T? {
        get {
            if let data = UserDefaults.standard.object(forKey: key) as? Data {
                return try? JSONDecoder().decode(T.self, from: data)
            }
            return nil
        }
        set {
            if let encoded = try? JSONEncoder().encode(newValue) {
                UserDefaults.standard.set(encoded, forKey: key)
            }
        }
    }
}

我将值存储在以下类中:

class AppState: ObservableObject {
    @UserDefault(key: "achievements") var achievements: [String : Bool]?
}

在我的Struct中,我试图读取值,但总是得到nil。我错过了什么?

struct XXX {
   AppState().achievements             = [:]
   AppState().achievements?["Normal"] = true
   print("ACHIEVEMENTS")
   print(AppState().achievements)
}

我得到nil,当我试图打开这个值时应用崩溃了。我需要做什么来读写我的成就变量?

cbjzeqam

cbjzeqam1#

除了结构问题(您似乎将裸表达式放在了struct的主体中,而这些表达式应该放在func中),问题归结为在最初创建achievements时没有引用AppState的同一个示例。
每次调用AppState()时,都创建了一个新示例。

func testWithProblem() {
   // Creating an instance of AppState and setting achievements...
   AppState().achievements = [:]
   // Creating another instance! The first instance is now gone from memory.
   // achievements on this instance is nil, so the next line has no effect.
   AppState().achievements?["Normal"] = true
   print("ACHIEVEMENTS")
   // Yet another instance...
   print(AppState().achievements)
}

确保引用的是同一个示例。

func testItWorksNow() {
   // You need to use the same instance...
   let appState = AppState()
   appState.achievements = [:]
   // So this line will refer to the same achievements dict as you've just created.
   appState.achievements?["Normal"] = true
   print("ACHIEVEMENTS")
   print(appState.achievements)
}

相关问题