Swift 4中的KeyPath是否可以获取KVC-String?

8

我目前正在处理的一个项目中,从我所接收的KeyPath实例中获取KVC字符串将非常有用。以下是一个简短的示例:

struct Person {
    var name: String
}

let propertyCache = ["name": "something"]

func method<T>(_ keypath: KeyPath<Person, T>) -> T? {
    let kvcName = keypath.kvc
    return propertyCache[kvcName]
}

这可能看起来并不是很有用,但在我的项目中是有用的 :) 我找到了KeyPath上的一个属性,叫做_kvcKeyPathString,它也是公共的,但每次我尝试使用它时都返回nil。 或者可能有可能利用反射吗?提前感谢您的想法/解决方案!


如果您使用@objc标记属性,则_kvcKeyPathString将具有一个值,因为它存在以支持互操作性。 - allenh
我希望我们能够获得更多的反射特性,不仅限于关键路径。再次感谢您的回答,即使它没有解决我的问题,@objc属性是正确的。您能否创建一个官方答案,以便我可以接受?这样对其他人来说会更好找到。 - Ben
我想要的是相反的:我有一个字符串(来自解析XML),我想将其转换为Swift 4的键路径,以便我不必使用Cocoa KVC。例如,“firstName”应该被转换为\Person.firstName - matt
@matt 这也是一个有效的用例!但据我所知目前还不可能 :/ - Ben
1
我担心你是对的。这很遗憾,因为有时确实存在合法的情况,你得到的是一个字符串,而你想将其映射到一个属性上。我想放弃Cocoa KVC,但它可以做到这一点,而Swift KeyPath则不能。 - matt
显示剩余3条评论
1个回答

13

我目前不知道一种纯Swift的方法来以字符串形式获取属性的名称。

但是,如果将@objc属性添加到该属性中,则_kvcKeyPathString实际上会有一个值,而不总是为空。此外,由于Swift结构体无法在Objective-C中表示,因此该方法仅适用于类。

最小工作示例:

class SomeClass {
    @objc var someProperty = 5
}

let keyPath = \SomeClass.someProperty
print(keyPath._kvcKeyPathString)

你知道使用这个属性是否算作使用私有API吗?只是想知道在发布的iOS应用中使用它是否会是一个非常糟糕的想法(当然,除了可维护性问题之外)。 - Andrew Bennet
@AndrewBennet 这不是私有API,只是在官方的Apple文档中没有记录,因此可能会在没有任何通知的情况下进行更改。他们使用前导下划线表示他们并不真正希望人们使用它,但我想他们本可以通过更多的努力将其标记为私有。来源 - allenh
谢谢!我可能会使用它,并编写一个单元测试来保护我免受行为变化的影响。 - Andrew Bennet
1
@Allen Humphreys,你能写一个示例代码吗?我尝试过了,但无法使用Swift 4.1。 - Kien Tran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接