Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
观测价值的Swift 4进近(分叉路径:…)_Swift_Swift4_Key Value Observing_Keypaths - Fatal编程技术网

观测价值的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你有消息来源吗?具体是什么?