首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用纯正Swift中的字符串名称使用反射获取属性的值

使用纯正Swift中的字符串名称使用反射获取属性的值
EN

Stack Overflow用户
提问于 2017-05-04 23:25:09
回答 2查看 2.3K关注 0票数 7

我想使用Swift (不是Objective运行时)反射来创建这样的方法:

代码语言:javascript
复制
func valueFor(property:String, of object:Any) -> Any? {
    ...
}

在某种程度上,我可以这样做:

代码语言:javascript
复制
func valueFor(property:String, of object:Any) -> Any? {
    let mirror = Mirror(reflecting: object)
    return mirror.descendant(property)
}

使用

代码语言:javascript
复制
class TestMe {
    var x:Int!
}

let t = TestMe()
t.x = 100
let result = valueFor(property: "x", of: t)
print("\(result); \(result!)")

这印出了我所期望的:

任择( 100 );100

当我这么做时:

代码语言:javascript
复制
let t2 = TestMe()    
let result2 = valueFor(property: "x", of: t2)
print("\(result2)")

产出如下:

任择(无)

这似乎是合理的,但如果我这样做了:

代码语言:javascript
复制
var x:Int!
print("\(x)")

这张打印出来:

而不是Optional(nil)。底线是,我在编程上很难用我的t2.x方法确定nil的值是nil

如果我继续使用以下代码进行上述代码:

代码语言:javascript
复制
if result2 == Optional(nil)! {
    print("Was nil1")
}

if result2 == nil {
    print("Was nil2")
}

这两个print语句都没有输出任何内容。

当我在Xcode中放置一个断点并使用调试器查看result2的值时,它显示:

代码语言:javascript
复制
▿ Optional<Any>
  - some : nil

因此,我的问题是:如何使用来自valueFor**?**的结果来确定原始成员变量是否为零?

Additional1:如果我这么做的话:

代码语言:javascript
复制
switch result2 {
case .some(let x):
    // HERE
    break
default:
    break
}

并在HERE上放置一个断点,x的值最终是nil。但是,即使我将它分配给一个Any?,将它与nil进行比较也不是真的。

Additional2:如果我这么做的话:

代码语言:javascript
复制
switch result2 {
case .some(let x):
    let z:Any? = x
    print("\(z)")
    if z == nil {
        print("Was nil3")
    }
    break
default:
    break
}

这只打印出(仅):

任择(无)

我觉得这特别奇怪。result2打印出完全相同的东西!

EN

回答 2

Stack Overflow用户

发布于 2017-05-05 02:11:23

这是个小问题,但我认为它会解决我的问题。我仍在寻找更好的解决方案:

代码语言:javascript
复制
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
    }
}
票数 2
EN

Stack Overflow用户

发布于 2021-05-20 13:41:43

嗯,我知道已经4年了,但我在Xcode 12上,仍然面临着同样的问题。由于这个问题似乎没有答案,我要补充一下对我有用的东西。

代码语言:javascript
复制
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检查可选选项,然后使用“一些”提取可选选项,您将返回一个真正的对象或零。当这是通过任何返回给呼叫者?返回,您现在可以不检查该值,并使该工作适当。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43794228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档