我想使用 Swift(不是 Objective-C 运行时)反射来创建这样的方法:
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!)")
这打印出了我所期望的:
Optional(100); 100
当我这样做时:
let t2 = TestMe()
let result2 = valueFor(property: "x", of: t2)
print("\(result2)")
输出是:
Optional(nil)
这似乎是合理的,除非我这样做:
var x:Int!
print("\(x)")
打印出来:
nil
而不是可选(nil)
。最重要的是,我在使用我的 valueFor
方法以编程方式确定 t2.x
的值为 nil
时遇到困难。
如果我继续上面的代码:
if result2 == Optional(nil)! {
print("Was nil1")
}
if result2 == nil {
print("Was nil2")
}
这些 print
语句都没有输出任何内容。
当我在 Xcode 中放置断点并使用调试器查看 result2
的值时,它显示:
▿ Optional<Any>
- some : nil
所以,我的问题是:如何使用 valueFor
的结果来确定原始成员变量是否为 nil?
附加 1: 如果我这样做:
switch result2 {
case .some(let x):
// HERE
break
default:
break
}
在HERE
下断点,x的值为nil
。但是,即使我将它分配给 Any?
,将它与 nil
进行比较也是不正确的。
附加 2: 如果我这样做:
switch result2 {
case .some(let x):
let z:Any? = x
print("\(z)")
if z == nil {
print("Was nil3")
}
break
default:
break
}
这会打印出(仅):
Optional(nil)
我觉得这特别奇怪。 result2
打印出完全相同的东西!
最佳答案
这有点hack,但我认为它会为我解决问题。我仍在寻找更好的解决方案:
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
}
}
关于swift - 使用反射在纯 Swift 中使用属性的字符串名称获取属性的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43794228/