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

丶灬走出姿态 提交于 2020-01-06 08:43:11

问题


I have a class which has 2 sets of getter & setters. 1 set is the traditional type. These work as expected:

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()
    }
}

The other gets/sets all properties at once.

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 always returns nil. However userProfile.email & userProfile.podId work as expected. Also, the direct getter (podSerialNum) works.

What am I missing?


回答1:


Adding a few steps to understand:

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

=>

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

Well, you'll see that podSNFromUserDefaults is not nil, it's podSNAsString which is. Why ? Because podSNFromUserDefaults is an Int/NSNumber, not a String. You can't cast it as a String like that. Use String(myInt).

And since we already know it's an Int, like you did for each single call, use integer(forKey:), and directly string(forKey:) also for the profileEmail, you don't need the as? String afterwards.

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

Side note:
You should get rid of the UserDefaults.standard.synchronize().

Tip:
If you have issues, don't forget to break multiple calls made in one line into various ones. It should be then easier to debug which step exactly doesn't work.



来源:https://stackoverflow.com/questions/55300399/why-does-1-of-these-getter-setters-work-and-the-others-dont

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!