返回

揭秘KVO:苹果的键值监听秘诀

IOS

KVO简介

KVO全称KeyValueObserving,中文译为键值监听,是苹果公司提供的事件通知机制。它允许对象监听另一个对象特定属性的改变,并在改变时接收到事件。

KVO基于观察者模式实现,监听对象(observer)通过调用addObserver:方法将自身注册为被监听对象(observable)的观察者,并指定要监听的属性。当被监听对象的属性发生改变时,KVO会自动通知监听对象,监听对象可以通过observeValueForKeyPath:ofObject:change:context:方法处理属性改变事件。

KVO使用

添加观察者

class MyClass: NSObject {
    @objc dynamic var name: String?
}

class Observer: NSObject {
    func observeNameChanges(object: MyClass) {
        object.addObserver(self, forKeyPath: "name", options: [.new, .old], context: nil)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "name" {
            let oldName = change?[.oldKey] as? String
            let newName = change?[.newKey] as? String
            print("Name changed from \(oldName ?? "") to \(newName ?? "")")
        }
    }
}

let myClass = MyClass()
let observer = Observer()
observer.observeNameChanges(object: myClass)

myClass.name = "John" // Prints "Name changed from nil to John"
myClass.name = "Mary" // Prints "Name changed from John to Mary"

移除观察者

myClass.removeObserver(observer, forKeyPath: "name")

KVO的常见问题

KVO何时会触发通知?

KVO会在被监听对象的属性发生改变时触发通知。属性改变包括:

  • 直接设置属性的值,例如myObject.name = "John"
  • 使用KVC修改属性的值,例如[myObject setValue:@"John" forKey:@"name"]
  • 通过其他对象间接修改属性的值,例如myObject.parent.name = "John"

KVO通知中包含哪些信息?

KVO通知包含以下信息:

  • 发生改变的属性的名称
  • 属性的旧值
  • 属性的新值
  • 一个上下文对象,用于存储与通知相关的信息

KVO与KVC有什么区别?

KVO和KVC都是苹果公司提供的键值编程机制,但它们在实现原理和使用方式上有所不同。

  • KVO是基于观察者模式实现的,允许对象监听另一个对象特定属性的改变,并在改变时接收到事件。
  • KVC是基于消息发送机制实现的,允许对象动态地访问和修改另一个对象属性的值,而无需直接访问属性的存储属性。

KVO与委托模式有什么区别?

KVO和委托模式都是苹果公司提供的对象间通信机制,但它们在实现原理和使用方式上也有所不同。

  • KVO是基于观察者模式实现的,允许对象监听另一个对象特定属性的改变,并在改变时接收到事件。
  • 委托模式是基于消息发送机制实现的,允许对象将特定任务委托给另一个对象执行,并通过协议定义委托对象与委托者的通信接口。

总结

KVO是苹果公司提供的一套强大的事件通知机制,它允许对象监听另一个对象特定属性的改变,并在改变时接收到事件。KVO在iOS、macOS等平台的开发中得到了广泛的应用,本文对KVO的原理、使用和常见问题进行了详细的讲解,希望能够帮助您深入理解并掌握这一强大的开发技术。