我有保存原语和确认对象的功能NSCoding
来UserDefaults
。
func set(_ value: Any?, forKey key: String) {
if let value = value {
if (value is NSCoding) {
let encodedValue = NSKeyedArchiver.archivedData(withRootObject: value)
UserDefaults.standard.set(encodedValue, forKey: key)
} else {
print("Storage: failed to save value for key \(key). Value must confirm to NSCoding protocol")
}
} else {
UserDefaults.standard.removeObject(forKey: key)
}
}
我想摆脱函数内部的一致性检查。所以函数必须只接受NSCoding
值。
我试图将函数的签名更改为:
func set(_ value: NSCoding?, forKey key: String)
和这个:
func set<T: Any>(_ value: T?, forKey key: String) where T: NSCoding
但是,我在每个函数调用中都会遇到编译错误。
在第一种情况下,我得到:
参数类型“***”不符合预期类型“NSCoding?”
在第二:
无法将“***”类型的值转换为预期的参数类型“_?”
我应该改变什么才能使它工作?
方法声明本身似乎没有问题
func set<T: Any>(_ value: T?, forKey key: String) where T: NSCoding {
if let value = value {
let encodedValue = NSKeyedArchiver.archivedData(withRootObject: value)
UserDefaults.standard.set(encodedValue, forKey: key)
} else {
UserDefaults.standard.removeObject(forKey: key)
}
}
但是编译错误指出你传递给这个函数的值可能不兼容 NSCoding
示例调用上述函数
self.set("abcd", forKey: "test")
给出错误
无法将“String”类型的值转换为预期的参数类型“_?”
另一方面称它为
self.set(NSString(string: "abcd"), forKey: "test")
工作良好。所以请确保您传递正确的参数:)
编辑 1:
基于 OP 的评论测试了泛型方法 Int
let test: Int = 100
self.set(test, forKey: "test")
导致同样的错误,但将其装箱为 NSNumber
let test: Int = 100
self.set(NSNumber(value: test), forKey: "test")
编辑2:
回答 OP 的评论
但是为什么字符串值通过 if (value is NSCoding) check in my original function?
let a: Any = "abcd"
if a is NSCoding {
debugPrint("am here")
}
那是因为您的 any 通过了NSCoding
检查,在您的情况下,无论您传递给函数的值是什么,您都将其类型转换为Any
并Any
通过检查:)
因此它在你的第一种方法中工作,但在泛型上失败了 :) 希望它有所帮助
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句