KVC Swift 2.1反射
我正试图实现一个KVC等价物,它是Swift(受使用反射的启发)KVC Swift 2.1反射,swift,reflection,kvc,Swift,Reflection,Kvc,我正试图实现一个KVC等价物,它是Swift(受使用反射的启发) valueForKey非常简单,使用反射来获取所有子项名称并检索适当的值。setValueForKey已经证明非常棘手,因为快速反射似乎是只读的(因为读写会打破反射教条) 协议KVC{ var codeables:[字符串:Any.Type]{get} 变异func setValue(值:T,forKey:String) func getValue(键:String)->T? } 扩展KVC{ var codeables:[字符串
valueForKey
非常简单,使用反射来获取所有子项名称并检索适当的值。setValueForKey
已经证明非常棘手,因为快速反射似乎是只读的(因为读写会打破反射教条)
协议KVC{
var codeables:[字符串:Any.Type]{get}
变异func setValue(值:T,forKey:String)
func getValue(键:String)->T?
}
扩展KVC{
var codeables:[字符串:Any.Type]{
变量字典:[字符串:Any.Type]=[:]
让镜子=镜子(反射:自身)
给镜子里的孩子{
如果let label=child.label{
字典[标签]=镜像(反射:child.value).主题类型
}
}
返回字典
}
变异func setValue(值:T,forKey:String){
如果让valueType=self.codeables[key],其中valueType==value.dynamicType{
}
}
func getValue(键:String)->T{
让镜子=镜子(反射:自身)
给镜子里的孩子{
如果let label=child.label,则value=child.value为?T,其中label==key{
返回值
}
}
归零
}
}
Swift中是否有任何方法可以在不使用Objective-C运行时或强制conformer是
NSObject
的子类的情况下设置动态键路径值?答案似乎是否定的,但有一些巧妙的解决方法,例如,尽管我不喜欢conformer的责任。Swifts反射是100%只读,因此答案是否定的,您必须使用一些讨厌的解决方法(顺便说一句,反射非常慢)是否有比反射更好的方法,而不是像反射那么慢?而且就KVC而言,似乎是使用1)objc运行时或2)在conformer上施加一些客户端协议,因为ObjectMapper使用NSObject作为类的基本类型,我确信没有其他方法可以设置密钥的值。在大多数情况下,反射速度足够快。在您的例子中,在getValue函数中执行镜像。然后,它将在每次您想要获取值时执行。如果要访问多个值,那么还应该创建getValuesDictionary,以便从中获取数据。
protocol KVC {
var codeables: [String: Any.Type] { get }
mutating func setValue<T>(value: T, forKey key: String)
func getValue<T>(key: String) -> T?
}
extension KVC {
var codeables: [String: Any.Type] {
var dictionary: [String: Any.Type] = [:]
let mirror = Mirror(reflecting: self)
for child in mirror.children {
if let label = child.label {
dictionary[label] = Mirror(reflecting: child.value).subjectType
}
}
return dictionary
}
mutating func setValue<T>(value: T, forKey key: String) {
if let valueType = self.codeables[key] where valueType == value.dynamicType {
}
}
func getValue<T>(key: String) -> T? {
let mirror = Mirror(reflecting: self)
for child in mirror.children {
if let label = child.label, value = child.value as? T where label == key {
return value
}
}
return nil
}
}