玩键值观察(KVO)(Swift3)

什么是键值观察? 顾名思义,它是一种允许一个对象观察另一个对象的属性的机制。

什么是“可观察的”?

要观察到,它必须继承自NSObject ,并且必须具有动态属性。 动态表示可以在运行时动态分配属性。

我的可观察对象是否需要为类? 可以是结构还是枚举?

可观察的属性必须是类(Objective-C类型),因此无法动态观察Swifty类型(例如结构和枚举)。 Foundation框架中定义的每个类对象均符合NSKeyValueObserving协议。

观察者实际上在做什么?

当一个对象(即一个viewController)被添加为观察者时,它所观察的属性发生变化时,它会收到一个通知。

什么是实现键值观察器的示例?

因此,假设我有一个WKWebView对象,并且想要观察其属性之一, estimatedProgress

首先,我需要添加一个观察者,该观察者将收到有关EstimateProgress更改的通知。 在这里,我将ViewController设为观察者。

在上面的第21行,我在seaWebView上调用.addObserver方法,该方法是WKWebView的实例。 .addObserver方法具有四个参数:observer,forKeyPath,options和context。

观察者 =正在侦听的对象(又名我的ViewController,自我)

forKeyPath =我正在观察的属性(又名EstimatedProgress )。 注意:这是字符串文字。 此KVO是Objective-C机制,因此键和键路径是字符串。 小心输入这个坏男孩!

options =代表观察者收到的信息类型。 类型包括.new (属性的新值) 、. old (属性的旧值) 、. initial (甚至在添加.addObserver方法之前发送给观察者的立即值) 、. prior (发送通知)任何更改之前和之后)。

context =一条通知消息,其中包含在相应的更改通知中传递回观察者的任意数据。 我在上面设置为零。

其次 ,我需要实现observeValue()方法。

在第31行,我实现了watchValue方法,该方法接受四个参数,keyPath,object,change和context。

keyPath =您正在观察的属性(又名EstimatedProgress

object =引用正在观察的对象

变化=观察到的变化存储在[NSKeyValueChangeKey:Any]?的词典中[NSKeyValueChangeKey:Any]? 因此,所有观察到的特性变化都保存在该词典中。

context =此上下文与.addObserver方法中添加的上下文相同(此处为nil)

在上面的watchValue方法中,我检查要观察的keyPath是我添加到观察器中的keyPath,然后编写一条打印语句,打印出WKWebView加载时估计进度的百分比。

观看下面的视频(为慢速加载模拟器道歉)以查看其运行。

尽管Swift会在不再需要实例时自动取消分配实例,但是通过键值观察,我们需要自己清理。

我在deinit闭包中的第38行删除了观察者。

作为记录,有两种方法可以显式删除观察者:

  • removeObserver(_:forKeyPath:)
  • removeObserver(_:forKeyPath:context:)

在XCode中还有许多其他使用键值观察的方法,但是由于它仅适用于类,因此观察需要与结构和枚举结合使用的其他方法。 构建代码时应考虑这一点。

在下面发表评论,让我知道您如何使用键值观察。

您可以在这里找到我的代码。

我给你留了一张美丽的海洋生物照片。

资源:

键值观察编程指南— Apple文档