Swift 4 引入了一系列具体的Key-Path 类型,一个新的Key-Path Expression来生成它们,以及一个新的基于闭包的观察函数,可用于继承的类NSObject
。
使用这组新功能,您的特定示例现在可以更简洁地表达:
self.observation = object.observe(\.keyPath) {
[unowned self] object, change in
self.someFunction()
}
涉及的类型
键路径语法
Key-Path Expression的一般语法遵循具体类型名称(包括任何通用参数)和一个或多个属性、下标或可选链接/强制展开后缀的链的形式。此外,如果 keyPath 的 Type 可以从 context 中推断出来,则可以省略,从而得到最简洁的.\Type.keyPath
Type
keyPath
\.keyPath
这些都是有效的键路径表达式:
\SomeStruct.someValue
\.someClassProperty
\.someInstance.someInnerProperty
\[Int].[1]
\[String].first?.count
\[SomeHashable: [Int]].["aStringLiteral, literally"]!.count.bitWidth
所有权
您是函数返回的NSKeyValueObservation
实例的所有者,这意味着您不必也不必再这样做;相反,只要您需要观察观察,您就会一直强烈地参考它。observe
addObserver
removeObserver
您也不需要这样做invalidate()
:它会很deinit
优雅。因此,您可以让它一直存在,直到持有它的实例死亡,通过nil
引用手动停止它,或者甚至invalidate()
在您出于某种臭名昭著的原因需要保持实例存活时调用。
注意事项
您可能已经注意到,观察仍然潜伏在 Cocoa 的 KVO 机制的范围内,因此它仅适用于 Obj-C 类和 Swift 类继承NSObject
(每个 Swift-dev 最喜欢的类型),并附加要求您打算观察的任何值,必须标记为@objc
(每个 Swift 开发者最喜欢的属性)并声明为dynamic
.
话虽这么说,整体机制是一个值得欢迎的改进,特别是因为它设法 Swiftify 观察NSObjects
从我们可能碰巧需要使用的模块(例如Foundation
)导入的,并且不会冒削弱我们努力获得的表达能力的风险。击键。
作为旁注,仍然需要Key-Path字符串表达式来动态访问 NSObject
KVC 的属性或调用value(forKey(Path):)
超越 KVO
Key-Path Expressions 的功能远不止 KVO。\Type.path
表达式可以存储为KeyPath
对象以供以后重用。它们有可写、部分和类型擦除的味道。它们可以增强为合成而设计的 getter/setter 函数的表达能力,更不用说它们在让那些最有胆量的人深入研究 Lenses 和 Prisms 等功能概念世界中所起的作用。我建议您查看下面的链接,以了解更多关于他们可以打开的许多开发门。
链接:
键路径表达式@ docs.swift.org
KVO 文档@Apple
Swift Evolution Smart KeyPaths 提案
Ole Begemann 的 Whats-new-in-Swift-4 操场与 Key-Path 示例
WWDC 2017 视频:Foundation 中的新增 功能 SKP 4:35 和 KVO 19:40。