KVO vs NSNotification vs 协议委托

作者:编程家 分类: ios 时间:2025-10-12

KVO vs NSNotification vs 协议/委托

在iOS开发中,我们经常需要实现对象之间的通信和数据传递。为了实现这一目的,我们可以使用KVO(键值观察)、NSNotification(通知)和协议/委托这三种方式。本文将介绍它们的特点和适用场景,并提供相应的案例代码。

1. KVO(键值观察)

KVO是一种观察者模式,它通过观察对象的属性值的变化来实现通信。当被观察的属性值发生改变时,观察者对象将自动收到通知。KVO适用于一对一的对象通信,即一个对象观察另一个对象的属性变化。

使用KVO的步骤如下:

1. 注册观察者:通过调用被观察对象的`addObserver:forKeyPath:options:context:`方法注册观察者。

2. 实现观察者方法:观察者对象需要实现`observeValueForKeyPath:ofObject:change:context:`方法,用于处理属性变化的通知。

3. 移除观察者:当观察者对象不再需要观察时,需要调用`removeObserver:forKeyPath:`方法将观察者对象从被观察对象中移除。

下面是一个使用KVO的示例代码:

swift

class Person: NSObject {

@objc dynamic var name: String

init(name: String) {

self.name = name

}

}

class Observer: NSObject {

var person: Person

init(person: Person) {

self.person = person

super.init()

person.addObserver(self, forKeyPath: "name", options: .new, context: nil)

}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

if keyPath == "name" {

if let newName = change?[.newKey] as? String {

print("Person's name changed to \(newName)")

}

}

}

deinit {

person.removeObserver(self, forKeyPath: "name")

}

}

let person = Person(name: "John")

let observer = Observer(person: person)

person.name = "Tom" // 输出:Person's name changed to Tom

2. NSNotification(通知)

NSNotification是一种广播机制,用于在多个对象之间传递消息。通过发送通知的方式,我们可以实现一对多的对象通信。通知中心(NSNotificationCenter)负责发送和接收通知。

使用NSNotification的步骤如下:

1. 注册观察者:观察者对象通过调用通知中心的`addObserver:selector:name:object:`方法注册观察者。

2. 实现观察者方法:观察者对象需要实现一个方法,该方法的名称由上一步中的`selector`参数指定,用于处理接收到的通知。

3. 发送通知:发送通知的对象通过调用通知中心的`postNotificationName:object:`方法发送通知。

下面是一个使用NSNotification的示例代码:

swift

class Sender {

func sendMessage() {

NotificationCenter.default.post(name: NSNotification.Name("MessageNotification"), object: self, userInfo: ["message": "Hello"])

}

}

class Receiver {

init() {

NotificationCenter.default.addObserver(self, selector: #selector(handleMessage(_:)), name: NSNotification.Name("MessageNotification"), object: nil)

}

@objc func handleMessage(_ notification: Notification) {

if let message = notification.userInfo?["message"] as? String {

print("Received message: \(message)")

}

}

}

let sender = Sender()

let receiver = Receiver()

sender.sendMessage() // 输出:Received message: Hello

3. 协议/委托

协议/委托是一种对象间的通信方式,通过定义一组方法和属性的协议,一个对象可以委托给另一个对象来实现这些方法和属性。协议/委托适用于一对一或一对多的对象通信。

使用协议/委托的步骤如下:

1. 定义协议:通过定义一个协议,包含需要实现的方法和属性。

2. 委托对象:委托对象需要遵循定义的协议,并实现协议中的方法和属性。

3. 设置委托:将委托对象赋值给需要委托的对象的属性。

下面是一个使用协议/委托的示例代码:

swift

protocol MessageDelegate: AnyObject {

func didReceiveMessage(message: String)

}

class Sender {

weak var delegate: MessageDelegate?

func sendMessage() {

delegate?.didReceiveMessage(message: "Hello")

}

}

class Receiver: MessageDelegate {

init() {

let sender = Sender()

sender.delegate = self

sender.sendMessage()

}

func didReceiveMessage(message: String) {

print("Received message: \(message)")

}

}

let receiver = Receiver() // 输出:Received message: Hello

KVO、NSNotification和协议/委托是iOS开发中常用的对象通信方式。根据不同的场景和需求,我们可以选择适合的方式来实现对象之间的通信和数据传递。KVO适用于一对一的对象通信,NSNotification适用于一对多的对象通信,而协议/委托适用于一对一或一对多的对象通信。