我想使用Swift(不是Objective-C运行时)Reflection来创建这样的方法:
func valueFor(property:String, of object:Any) -> Any? {
...
}
Run Code Online (Sandbox Code Playgroud)
在某种程度上,我可以这样做:
func valueFor(property:String, of object:Any) -> Any? {
let mirror = Mirror(reflecting: object)
return mirror.descendant(property)
}
Run Code Online (Sandbox Code Playgroud)
同
class TestMe {
var x:Int!
}
let t = TestMe()
t.x = 100
let result = valueFor(property: "x", of: t)
print("\(result); \(result!)")
Run Code Online (Sandbox Code Playgroud)
这打印出我期望的东西:
可选(100); 100
当我做:
let t2 = TestMe()
let result2 = valueFor(property: "x", of: t2)
print("\(result2)")
Run Code Online (Sandbox Code Playgroud)
输出是:
可选(无)
这似乎是合理的,除非我这样做:
var x:Int!
print("\(x)")
Run Code Online (Sandbox Code Playgroud)
打印出:
零
而不是Optional(nil).底线是我有困难编程确定的值t2.x被nil使用我的valueFor方法.
如果我继续上面的代码:
if result2 == Optional(nil)! {
print("Was nil1")
}
if result2 == nil {
print("Was nil2")
}
Run Code Online (Sandbox Code Playgroud)
这些print陈述都没有输出任何内容.
当我将断点放入Xcode并查看result2调试器的值时,它显示:
? Optional<Any>
- some : nil
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:如何使用结果确定原始成员变量是否为零valueFor?
附加1: 如果我这样做:
switch result2 {
case .some(let x):
// HERE
break
default:
break
}
Run Code Online (Sandbox Code Playgroud)
并且在断点处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
}
Run Code Online (Sandbox Code Playgroud)
这打印出来(仅):
可选(无)
我发现这特别奇怪.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
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
806 次 |
| 最近记录: |