我使用泛型类型并设置了一个nil值,但是结果是`nil == nil`为false如何解决这个问题呢?

问题描述

代码输出值为nil,但是value == nil为false。我该怎么做。

import Foundation

struct Token: Codable {
    var token: String
    var refreshToken: String
}

class User {

    @Storage(key: "User.Name.Token",defaultValue: Token(token: "testToken",refreshToken: "TestRefreshToken"))
    var token: Token?

    var isLogined: Bool {
        return token != nil
    }

    static let shared = User()
    private init() { }

    func logout() {
        token = nil
    }
}

@propertyWrapper
struct Storage<T: Codable> {
    private let key: String
    private let defaultValue: ()->T

    init(key: String,defaultValue: @escaping @autoclosure ()->T) {
        self.key = key
        self.defaultValue = defaultValue
    }

    var wrappedValue: T {
        get {
            guard let data = UserDefaults.standard.object(forKey: key) as? Data,let value = try? JSONDecoder().decode(T.self,from: data) else {
                return defaultValue()
            }
            print( "value is \(value)  " +  " but  \(value == nil)")
            return value
        }

        set {
            guard newValue != nil else {
                UserDefaults.standard.removeObject(forKey: key)
                return
            }
            let data = try? JSONEncoder().encode(newValue)
            UserDefaults.standard.set(data,forKey: key)
        }
    }
}

print( "before \(User.shared.token)")
User.shared.logout()
print( "after \(User.shared.token)")

解决方法

如果您希望包装的值是可选的,则可以将其更改为:

var wrappedValue: T? { // <- make it optional
    get {
        guard let data = UserDefaults.standard.object(forKey: key) as? Data,let value = try? JSONDecoder().decode(T.self,from: data) else {
            return defaultValue()
        }
        // after guard-let the `value` will never be `nil`
        print("value is \(value)")
        return value
    }

    set {
        guard newValue != nil else {
            UserDefaults.standard.removeObject(forKey: key)
            return
        }
        let data = try? JSONEncoder().encode(newValue)
        UserDefaults.standard.set(data,forKey: key)
    }
}

请注意,如果解码失败,这里的value可以是nil

let value = try? JSONDecoder().decode(T.self,from: data)

但是,如果您使用guard-let,则如果值是defaultValue(),它将返回nil,并且永远不会超出guard块:

guard let value = try? JSONDecoder().decode(T.self,from: data) else {
    return defaultValue()
}
// here `value` can't be `nil`