我想使用Swift (不是Objective运行时)反射来创建这样的方法:
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!)")这印出了我所期望的:
任择( 100 );100
当我这么做时:
let t2 = TestMe()
let result2 = valueFor(property: "x", of: t2)
print("\(result2)")产出如下:
任择(无)
这似乎是合理的,但如果我这样做了:
var x:Int!
print("\(x)")这张打印出来:
零
而不是Optional(nil)。底线是,我在编程上很难用我的t2.x方法确定nil的值是nil。
如果我继续使用以下代码进行上述代码:
if result2 == Optional(nil)! {
print("Was nil1")
}
if result2 == nil {
print("Was nil2")
}这两个print语句都没有输出任何内容。
当我在Xcode中放置一个断点并使用调试器查看result2的值时,它显示:
▿ Optional<Any>
- some : nil因此,我的问题是:如何使用来自valueFor**?**的结果来确定原始成员变量是否为零?
Additional1:如果我这么做的话:
switch result2 {
case .some(let x):
// HERE
break
default:
break
}并在HERE上放置一个断点,x的值最终是nil。但是,即使我将它分配给一个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打印出完全相同的东西!
发布于 2017-05-05 02:11:23
这是个小问题,但我认为它会解决我的问题。我仍在寻找更好的解决方案:
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
}
}发布于 2021-05-20 13:41:43
嗯,我知道已经4年了,但我在Xcode 12上,仍然面临着同样的问题。由于这个问题似乎没有答案,我要补充一下对我有用的东西。
func valueFor(property: String, of object: Any) -> Any? {
let optionalPropertyName = "some"
let mirror = Mirror(reflecting: object)
if let child = mirror.descendant(property) {
if let optionalMirror = Mirror(reflecting: child), optionalMirror.displayStyle == DisplayStyle.optional {
return optionalMirror.descendant(optionalPropertyName)
} else {
return child
}
} else {
return nil
}
}通过使用Mirror检查可选选项,然后使用“一些”提取可选选项,您将返回一个真正的对象或零。当这是通过任何返回给呼叫者?返回,您现在可以不检查该值,并使该工作适当。
https://stackoverflow.com/questions/43794228
复制相似问题