观测价值的Swift 4进近(分叉路径:…)
我一直在努力寻找一个例子,但我所看到的在我的案例中不起作用 以下代码的等效项是什么:观测价值的Swift 4进近(分叉路径:…),swift,swift4,key-value-observing,keypaths,Swift,Swift4,Key Value Observing,Keypaths,我一直在努力寻找一个例子,但我所看到的在我的案例中不起作用 以下代码的等效项是什么: object.addObserver(self, forKeyPath: "keyPath", options: [.new], context: nil) override public func observeValue( forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : An
object.addObserver(self, forKeyPath: "keyPath", options: [.new], context: nil)
override public func observeValue(
forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
}
上面的代码是有效的,但我从SwiftLink得到一个警告:
在使用Swift 3.2或更高版本时,更喜欢新的带关键路径的基于块的KVO API
如果您能为我指出正确的方向,我将不胜感激。Swift 4引入了一个混凝土系列,一个新的生成它们的方法,以及一个新的基于闭包的函数,可用于继承
NSObject
的类
使用这组新功能,您的特定示例现在可以更简洁地表达:
self.observation = object.observe(\.keyPath) {
[unowned self] object, change in
self.someFunction()
}
涉及的类型
观察:
更改:
:编译时生成的类的实例\.keyPath
\Type.keyPath
,其中Type
是具体的类型名称(包括任何通用参数),而keyPath
是一个或多个属性、下标或可选链接/强制展开后缀的链。此外,如果可以从上下文推断出关键路径的类型,则可以省略它,从而生成最精练的\.keyPath
这些都是有效的密钥路径表达式:
\SomeStruct.someValue
\.someClassProperty
\.someInstance.someInnerProperty
\[Int].[1]
\[String].first?.count
\[SomeHashable: [Int]].["aStringLiteral, literally"]!.count.bitWidth
所有权
您是NSKeyValueObservation
实例的所有者,observate
函数返回,这意味着您不必再addobservator
或removeObserver
;相反,只要你需要你的观察,你就会一直保持对它的有力引用
您也不需要invalidate()。因此,您可以让它一直存在,直到持有它的实例死亡,通过nil
ing引用手动停止它,或者如果出于某种令人讨厌的原因需要保持实例的生存,甚至可以调用invalidate()
注意事项
正如您可能已经注意到的,observation仍然潜伏在Cocoa的KVO机制的范围内,因此它仅适用于继承NSObject
(每个Swift开发人员最喜欢的类型)的Obj-C类和Swift类,并附加了一项要求,即您想要观察的任何值都必须标记为@objc
(每个Swift开发人员最喜欢的属性)并声明dynamic
尽管如此,总体机制还是一个值得欢迎的改进,特别是因为它能够快速观察从我们可能需要使用的模块(例如,Foundation
)导入的NSObjects
),而且不会削弱我们通过每次击键努力获得的表达能力
作为旁注,仍然需要将NSObject
的属性调用到KVC或调用值(forKey(Path):)
超越KVO
关键路径表达式比KVO有更多的功能。\Type.Path
表达式可以存储为KeyPath
对象以供以后重用。它们具有可写、部分和类型擦除的风格。它们可以增强为组合而设计的getter/setter函数的表达能力,更不用说它们在允许ose拥有强大的胃,可以深入研究透镜和棱镜等功能概念。我建议您查看下面的链接,了解更多关于它们可以打开的许多开发门的信息
链接:
SKP为4:35,KVO为19:40。在iOS 10中使用此方法时,我在应用程序上遇到崩溃,请在答案中添加一些内容
在iOS 10中,您仍然需要在释放类之前删除观察器,否则将出现崩溃nsinternalinconsistenceexception
,说明:
类C
的实例A
已解除分配,而键值观察者仍在该实例中注册
要避免此崩溃,只需将您使用的observer属性设置为nil
deinit {
self.observation = nil
}
也许能帮上忙。这能回答你的问题吗?你能告诉我在哪里可以找到你所说的“所有权”吗节?我正在参考中查找它,但我没有看到它。@dava据我所知,在文本中最接近正式明确提及的是和的docstring。两者都将如预期的那样显示在Xcode的quickhelp上。我还添加了一个WWDC视频,并扩展了所有权节。回答得好!谢谢!这是同一个问题th通知。如果您使用基于块的方法,您需要在deinit中将返回值显式设置为nil。非基于块的观察器不需要这样做。很棒的附录!非常清楚,在较新的iOS上没有观察到这个问题,对吗?iOS 11会自动处理这个问题。我假设iOS 12也会这样做,但我还没有测试它。@ba你有消息来源吗?具体是什么?