Swift:KeyPath

来源:互联网 发布:淘宝破零方法 编辑:程序博客网 时间:2024/05/17 22:53

Swift 中可以使用 KeyPath 来获取属性值,语法为\Type.property.property.....

官方给出的示例:

class Animal: NSObject {    @objc var name: String    init(name: String) {        self.name = name    }}let llama = Animal(name: "Llama")let nameAccessor = \Animal.namelet nameCountAccessor = \Animal.name.countllama[keyPath: nameAccessor]// "Llama"llama[keyPath: nameCountAccessor]// "5"

\Animal.name 是一个KeyPath,通过 subscript 来获取 Animal 实例的 name 属性值。

另外,一说 KeyPath,肯定就能想到 KVCKVO,通过 #keyPath(Type.property.property.....) 来创建一个 key,就能使用 KVC 的方法 value(forKey:)value(forKeyPath:)KVO 的方法 addObserver(_:forKeyPath:options:context:)

官方给出示例:

class Person: NSObject {    @objc var name: String    @objc var friends: [Person] = []    @objc var bestFriend: Person? = nil    init(name: String) {        self.name = name    }}let gabrielle = Person(name: "Gabrielle")let jim = Person(name: "Jim")let yuanyuan = Person(name: "Yuanyuan")gabrielle.friends = [jim, yuanyuan]gabrielle.bestFriend = yuanyuan#keyPath(Person.name)// "name"gabrielle.value(forKey: #keyPath(Person.name))// "Gabrielle"#keyPath(Person.bestFriend.name)// "bestFriend.name"gabrielle.value(forKeyPath: #keyPath(Person.bestFriend.name))// "Yuanyuan"#keyPath(Person.friends.name)// "friends.name"gabrielle.value(forKeyPath: #keyPath(Person.friends.name))// ["Yuanyuan", "Jim"]

另外,\Animal.name#keyPath(Animal.name) 是两个完全不同的东西,通过输出可以看出:

print(\Animal.name)// Swift.ReferenceWritableKeyPath<__lldb_expr_146.Animal, Swift.String>print(#keyPath(Animal.name))// name

\Animal.name 用于 Swift 的下标访问,#keyPath(Animal.name) 用于 KVCKVO

参考 The Swift Programming Language (Swift 4)