为什么其中 1 个 getter/setters 起作用而其他的不起作用

Why does 1 of these getter/setters work and the others don't

我有一个 class,它有 2 套 getter 和二传手。 1套为传统型。这些按预期工作:

var userEmail : String
{
    get {
        return UserDefaults.standard.string(forKey: UserDefaultKeys.profileEmail) ?? ""
    }
    set (newValue) {
        UserDefaults.standard.set(newValue, forKey: UserDefaultKeys.profileEmail)
        UserDefaults.standard.synchronize()
    }
}

var podSerialNum : Int
{
    get {
        return UserDefaults.standard.integer(forKey: UserDefaultKeys.profilePodSN)
    }
    set (newValue) {
        UserDefaults.standard.set(newValue, forKey: UserDefaultKeys.profilePodSN)
        UserDefaults.standard.synchronize()
    }
}
var podID : Int
{
    get {
        return UserDefaults.standard.integer(forKey: UserDefaultKeys.profilePodID)
    }
    set (newValue) {
        UserDefaults.standard.set(newValue, forKey: UserDefaultKeys.profilePodID)
        UserDefaults.standard.synchronize()
    }
}

另一个gets/sets一次所有属性。

var userProfile: (email:String?, podSn:String?, podId:String?)
{
    get {
        return ( UserDefaults.standard.value(forKey: UserDefaultKeys.profileEmail) as? String,
                 UserDefaults.standard.value(forKey: UserDefaultKeys.profilePodSN) as? String,
                 UserDefaults.standard.value(forKey: UserDefaultKeys.profilePodID) as? String)
    }
    set {
        UserDefaults.standard.set(newValue.email,   forKey: UserDefaultKeys.profileEmail)
        UserDefaults.standard.set(newValue.podSn,     forKey: UserDefaultKeys.profilePodSN)
        UserDefaults.standard.set(newValue.podId,   forKey: UserDefaultKeys.profilePodID)

        UserDefaults.standard.synchronize()
    }
}

userProfile.podSn 始终 returns 无。然而 userProfile.emailuserProfile.podId 按预期工作。此外,直接 getter (podSerialNum) 有效。

我错过了什么?

加几步理解:

UserDefaults.standard.value(forKey: UserDefaultKeys.profilePodSN) as? String

=>

let podSNFromUserDefaults = UserDefaults.standard.value(forKey: UserDefaultKeys.profilePodSN)
let podSNAsString = podSNFromUserDefaults as? String

嗯,您会发现 podSNFromUserDefaults 不是 nil,而是 podSNAsString。 为什么 ?因为 podSNFromUserDefaultsInt/NSNumber,而不是 String。您不能像那样将其转换为 String。使用 String(myInt).

并且由于我们已经知道它是一个 Int,就像您对每个调用所做的那样,使用 integer(forKey:),并且直接 string(forKey:) 也用于 profileEmail,您不需要as? String 之后。

var userProfile: (email: String?, podSn: String?, podId: String?)
{
    get {
        return (UserDefaults.standard.string(forKey: UserDefaultKeys.profileEmail),
                String(UserDefaults.standard.integer(forKey: UserDefaultKeys.profilePodSN)),
                String(UserDefaults.standard.integer(forKey: UserDefaultKeys.profilePodID))
    }
}

旁注:
你应该去掉 UserDefaults.standard.synchronize().

提示:
如果您遇到问题,请不要忘记将一行中的多个调用分成多个调用。然后应该更容易调试哪一步到底不起作用。