swift - 使用反射在纯 Swift 中使用属性的字符串名称获取属性的值

标签 swift reflection

我想使用 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/

相关文章:

java - libgdx - 确定哪个平台正在运行

c# - 在 C# 2.0 中使用 Invoke 调用时,参数从 null 转换为 DateTime.MinValue

java - 如何使用属性名称识别 setter 方法?

swift - 如何在 Swift 4 中使用 JSONEncoder 对字典进行编码

swift - 访问 EKCalendar

ios - 即使我重新启动 iPhone,如何保存分数?

java - 表单值上的 getMethod 安全吗?

c# - 如何获取类的属性列表?

swift - 如何使用 Overlay Swift 从底部菜单创建向上滑动

swift - 如何定义特定类型的间接枚举情况