引言
在 Object-C 的开发中,键(key)是一个字符串类型,它标识对象的一个属性。键路径(keyPath) 是一串带分割点键(key),它指定要遍历对象属性序列。键值编码(KVC)通常使用键和键路径,这是一种使用字符串标识符间接访问对象属性和关系的机制。键和键路径也用于键值观察(KVO),这是一种机制,当另一个对象的属性发生变化时,可以直接通知对象。
keyPath 的使用
1. 创建一个测试类 'Person'
/*!
创建一个类
*/
class Person: NSObject {
// TODO: 创建参数
@objc var name : String?
var address : String?
var contact : [Person] = []
// TODO: 初始化
init(name:String , address:String) {
super.init()
self.name = name
self.address = address
}
}
2. 创建一个 'Person' 类的对象
// TODO:创建 'Person' 类的对象
let NetWork = Person.init(name: "NetWork小贱", address: "北京-朝阳")
let NetWork1 = Person.init(name: "NetWork小贱-All", address: "北京-朝阳-高碑店")
NetWork.contact.append(NetWork1)
3. 'Person' 类属性值获取
1> 说明
在 Swift 中,可以使用键路径表达式来创建访问属性的关键路径。例如,可以使用 \ Person.address 键路径表达式来访问所示的人物类的地址属性。使用键路径表达式创建的关键路径包括关于它们引用的属性的类型信息。将一个关键路径应用到实例,会产生与直接访问该实例属性相同类型的值。键路径表达式接受属性引用和链接的属性引用,例如 \Person.contact[0].address 。
2> 'NetWork' 对象的名字
- 第一种方法(过去方法)
// TODO:获取 'NetWork' 的名字
let name = NetWork.name
print(name!)
// 输出:NetWork小贱
- 第二种方法
// TODO:获取 'NetWork' 的名字
let name1 = NetWork.value(forKey: #keyPath(Person.name))
print(name1!)
//输出:NetWork小贱
注释:#keyPath 字符串表达式的语法类似于选择器表达式(#selector)的语法。其中使用这种方法获取对象的属性值时,属性要 @objc 修饰,否则会报错(Argument of '#keyPath' refers to non-'@objc' property 'name')。
- 第三种方法
let nameKey = \Person.address
let name2 = NetWork[keyPath:nameKey]
print(name2!)
// 输入:北京-朝阳
4. '#keyPath(Person.name)' 和 '\Person.address' 的区别
// TODO: ‘#keyPath(Person.name)’ 和 ‘\Person.address’ 的区别
print("#keyPath(Person.name) 的输出")
print(#keyPath(Person.name))
print("'\'Person.address 的输出")
print(nameKey)
/*
输出结果:
#keyPath(Person.name) 的输出:
name
\Person.address 的输出:
Swift.ReferenceWritableKeyPath<KeyPath.Person, Swift.Optional<Swift.String>>
从输出结果可以看到 '\Person.address' 和 '#keyPath(Person.name)' 是两个不同的对象。'#keyPath(Person.name)' 是 String 类型; '\Person.address' 是字典类型
*/
5. keyPath 路径获取属性值
// TODO: 对象里面获取对象的参数
let cName = NetWork.contact[keyPath:\[Person].[0].name]
print(cName!)
// 输出:NetWork小贱-All
注释:键路径表达式接受属性引用和链接的属性引用。
6.通过keyPath 来给对象赋值
// TODO: 对象里面赋值对象的参数
NetWork.contact[keyPath:\[Person].[0].address] = "黑龙江"
// 获取其值
print(NetWork.contact[0].address!)
// 输出:黑龙江
总结
在Swift中可以使用# keyPath 字符串表达式创建compiler-checked键和键路径可以使用现有的方法如value(forKey:)和value(forKeyPath:),和KVO方法像addObserver(_:forKeyPath: options: context:)。#keyPath 字符串表达式接受链接方法或属性引用。它还支持通过链中的可选值进行链接,比如#keyPath(Person.bestFriend.name)。与使用键路径表达式创建的关键路径不同,使用#keyPath string表达式创建的关键路径不会传递有关它们引用的属性或方法的类型信息,这些属性或方法引用了接受关键路径的 Api。