iOS 知识点面试必看首页投稿(暂停使用,暂停投稿)

iOS:KVO 实现观察者模式

2016-12-31  本文已影响595人  Linsw

文章结构

前言

在 iOS 开发中,常常需要在不同的对象、不同的视图(View)或不同的视图控制器(ViewController)之间通信,传递数据。主要的实现方法有:

这些方法各有优劣,在不同的情况下选用合适的方法是最好的。因此掌握这些方法,才能更好地应对各种开发难题。KVO 是本文关注的重点。

KVO 简介

在 Apple 的应用开发里 KVO 提供了一个途径,使对象(观察者)能够观察其他对象(被观察者)的属性,当被观察者的属性发生变化时,观察者就会被告知该变化。这其实就对应设计模式中的观察者模式。

观察者:Observer,the observing object;被观察者:the observed object

前提条件

在实现 KVO 之前,需要确保被观察的对象是支持 KVO 的。通常继承自 NSObject 的对象都会自动支持 KVO。对于非继承自 NSObject 的类,也可以手动实现 KVO 支持

适用场景

KVO 能很方便地实现模型(Model)和控制器(Controller)之间的通信。主要的应用场景有:

KVO 能够实现一对多、多对多、多对一的观察。也就是说,KVO 没有限制观察者和被观察者的数量。当同时观察多个对象时,不但对象本身发生改变时会告知观察者,而且被观察对象发生替换、删除或插入等操作时也会告知观察者。

实现 KVO:注册观察者和观察者方法

基本流程

  1. 添加观察者:addObserver:forKeyPath:options:context:
  2. 实现观察响应方法:observeValueForKeyPath:ofObject:change:context:
  3. 在观察者 deallocted 之前移除观察者: removeObserver:forKeyPath:

添加观察者

observedObject.addObserver:forKeyPath:options:context:

注意:

class ObservedObjectClass: NSObject {
//在 Swift 中要用 dynamic 标记被观察的属性
    dynamic private var observedProperty = ""
    ...
}

观察响应方法:

所有的观察者都必须实现观察响应方法:
observeValueForKeyPath:ofObject:change:context:

移除观察者

当一个对象不再需要观察另一个对象时,就需要移除观察。

observedObject.removeObserver:forKeyPath:context:

这个方法和添加观察者的方法是对应的。

移除观察者需要注意以下几点:

总结

KVO 能够在复杂的关系网中直接观察某个对象,合理的使用 KVO 能够简化代码。但是 KVO 也有很多坑,稍有不慎就会抛出异常或者无法建立观察。在实践中,还是应该选择合适的方法来完成对象间的通信,熟练应对各种情况。

欢迎访问我的Github:LinShiwei (Lin Shiwei) · GitHub

有任何疑问的话,欢迎在下方评论区讨论。

上一篇 下一篇

猜你喜欢

热点阅读