我用的是泛型,设置了一个nil值,但是结果是`nil == nil`是false。如何解决这个问题呢?
I use the generic type and set a nil value, but the result is `nil == nil` is false. How to solve this problem?
代码将打印值为 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
它会 return defaultValue()
如果值是 nil
并且永远不会超过 guard
块:
guard let value = try? JSONDecoder().decode(T.self, from: data) else {
return defaultValue()
}
// here `value` can't be `nil`
代码将打印值为 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
它会 return defaultValue()
如果值是 nil
并且永远不会超过 guard
块:
guard let value = try? JSONDecoder().decode(T.self, from: data) else {
return defaultValue()
}
// here `value` can't be `nil`