KVC Swift 2.1反射

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:[字符串

我正试图实现一个KVC等价物,它是Swift(受使用反射的启发)

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