使用反射在纯Swift中使用它的字符串名称获取属性的值
发布时间:2020-12-14 05:01:00 所属栏目:百科 来源:网络整理
导读:我想使用 Swift(不是Objective-C运行时)Reflection来创建这样的方法: func valueFor(property:String,of object:Any) - Any? { ...} 在某种程度上,我可以这样做: func valueFor(property:String,of object:Any) - Any? { let mirror = Mirror(reflecting:
我想使用
Swift(不是Objective-C运行时)Reflection来创建这样的方法:
func valueFor(property:String,of object:Any) -> Any? { ... } 在某种程度上,我可以这样做: func valueFor(property:String,of object:Any) -> Any? { let mirror = Mirror(reflecting: object) return mirror.descendant(property) } 同 class TestMe { var x:Int! } let t = TestMe() t.x = 100 let result = valueFor(property: "x",of: t) print("(result); (result!)") 这打印出我期望的东西:
当我做: let t2 = TestMe() let result2 = valueFor(property: "x",of: t2) print("(result2)") 输出是:
这似乎是合理的,除非我这样做: var x:Int! print("(x)") 打印出:
而不是可选(零).底线是我使用我的valueFor方法以编程方式确定t2.x的值为nil时遇到困难. 如果我继续上面的代码: if result2 == Optional(nil)! { print("Was nil1") } if result2 == nil { print("Was nil2") } 这些打印语句都没有输出任何内容. 当我将断点放入Xcode并使用调试器查看result2的值时,它显示: ? Optional<Any> - some : nil 所以,我的问题是:如何使用valueFor的结果确定原始成员变量是否为零? Additional1: switch result2 { case .some(let x): // HERE break default: break } 并在此处设置断点,x的值结果为零.但是,即使我将它分配给Any?,将它与nil进行比较也不是真的. Additional2: switch result2 { case .some(let x): let z:Any? = x print("(z)") if z == nil { print("Was nil3") } break default: break } 这打印出来(仅):
我发现这特别奇怪. result2打印出完全相同的东西! 解决方法
这有点像黑客,但我认为这将解决我的问题.我仍在寻找更好的解决方案:
func isNilDescendant(_ any: Any?) -> Bool { return String(describing: any) == "Optional(nil)" } func valueFor(property:String,of object:Any) -> Any? { let mirror = Mirror(reflecting: object) if let child = mirror.descendant(property),!isNilDescendant(child) { return child } else { return nil } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |