06.通信设计和实践
目录介绍
- 01.Controller间如何通信
- 1.1 委托模式通信
- 1.2 使用通知中心通信
- 1.3 使用闭包通信
- 1.4 使用单例模式通信
- 1.5 共享数据模型通信
- 1.6 如何选择合适方式
01.Controller间如何通信
视图控制器(View Controller)之间可以通过多种方式进行通信。以下是一些常见的方法:
- 使用委托模式(Delegate Pattern):通过定义协议(Protocol)和委托(Delegate)来实现视图控制器之间的通信。
- 使用通知中心(Notification Center): 视图控制器可以通过通知中心发送和接收通知。
- 使用闭包(Closure):一个视图控制器可以将一个闭包作为参数传递给另一个视图控制器,并在需要时调用该闭包来传递数据或执行特定的操作。
- 使用单例模式(Singleton Pattern):通过创建一个全局可访问的单例对象,视图控制器之间可以共享数据和状态。
- 使用共享的数据模型:视图控制器之间可以共享一个数据模型对象,通过对该对象进行读写操作来进行通信。
1.1 委托模式通信
通过定义协议(Protocol)和委托(Delegate)来实现视图控制器之间的通信。
一个视图控制器可以成为另一个视图控制器的委托,并实现协议中定义的方法来接收和处理事件或数据。
如何在两个视图控制器之间使用委托模式进行通信。通过定义协议(Protocol)和委托(Delegate)来实现通信。代码如下所示
第一步:定义一个协议 DataDelegate,其中包含一个方法 didReceiveData
protocol DataDelegate: AnyObject {
func didReceiveData(data: String)
}
第二步:在B视图控制器 SenderViewController,声明委托属性和触发委托方法
class SenderViewController: UIViewController {
weak var delegate: DataDelegate?
//触发委托方法
func sendData() {
let data = "Hello, World!"
delegate?.didReceiveData(data: data)
}
}
第三步:在A视图控制器 ReceiverViewController中,设置协议委托并接收数据
//ReceiverViewController 类需要实现前面定义的协议 DataDelegate
class ReceiverViewController: UIViewController, DataDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let senderVC = SenderViewController()
//将自身设置为 SenderViewController 的委托
senderVC.delegate = self
senderVC.sendData()
}
func didReceiveData(data: String) {
print("Received data: \(data)")
}
}
通过委托模式,SenderViewController 和 ReceiverViewController 之间可以进行通信,并传递数据。
1.2 使用通知中心通信
视图控制器可以通过通知中心发送和接收通知。
一个视图控制器可以发送一个通知,而其他视图控制器可以通过注册为观察者来接收并响应该通知。
通知中心提供了一种发布-订阅模式,允许一个视图控制器发布通知,而其他视图控制器可以订阅并接收这些通知。
第一步:在B视图控制器 SenderViewController,使用 NotificationCenter 的 post 方法发布一个名为 "MyNotification" 的通知。
class SenderViewController: UIViewController {
func sendData() {
//发布一个名为 "MyNotification" 的通知。
NotificationCenter.default.post(name: NSNotification.Name("MyNotification"), object: nil)
}
}
第二步:在A视图控制器 ReceiverViewController,使用 NotificationCenter 的 addObserver 方法订阅名为 "MyNotification" 的通知,并指定一个处理通知的方法 handleNotification。
class ReceiverViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//订阅了该通知,并在接收到通知时打印出相应的消息
NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: NSNotification.Name("MyNotification"), object: nil)
}
@objc func handleNotification() {
print("Received notification")
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
注意的是,在 deinit 方法中,我们使用 NotificationCenter 的 removeObserver 方法取消订阅通知,以避免内存泄漏。
1.3 使用闭包通信
一个视图控制器可以将一个闭包作为参数传递给另一个视图控制器,并在需要时调用该闭包来传递数据或执行特定的操作。
第一步:创建一个发送数据的视图控制器 SenderViewController。声明了一个闭包属性 dataClosure,用于接收数据的回调。在 sendData 方法中,我们将数据传递给闭包。
class SenderViewController: UIViewController {
var dataClosure: ((String) -> Void)?
func sendData() {
let data = "Hello, World!"
dataClosure?(data)
}
}
第二步:创建一个接收数据的视图控制器 ReceiverViewController。将接收数据的闭包赋值给 dataClosure 属性。
class ReceiverViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let senderVC = SenderViewController()
senderVC.dataClosure = { [weak self] data in
self?.handleData(data: data)
}
}
func handleData(data: String) {
print("Received data: \(data)")
}
}
1.4 使用单例模式通信
通过创建一个全局可访问的单例对象,视图控制器之间可以共享数据和状态。
1.5 共享数据模型通信
视图控制器之间可以共享一个数据模型对象,通过对该对象进行读写操作来进行通信。
1.6 如何选择合适方式
选择合适的通信方式取决于你的具体需求和场景。以下是一些常见的情况和对应的通信方式:
- 委托模式(Delegate Pattern):适用于一对一的通信关系,其中一个对象(委托)将自身的行为委托给另一个对象(委托对象)。委托模式适用于需要回调和数据传递的情况,例如视图控制器之间的通信。
- 通知中心(Notification Center):适用于一对多的通信关系,其中一个对象发布通知,而其他对象可以订阅并接收这些通知。通知中心适用于需要广播消息的情况,例如系统事件、状态变化等。
- 闭包(Closure):适用于简单的一次性通信,其中一个对象将一个闭包传递给另一个对象,以便在需要时调用。闭包适用于需要传递回调或处理结果的情况,例如异步操作的回调。
- 共享数据模型:适用于需要在多个对象之间共享数据的情况。通过创建一个共享的数据模型对象,多个对象可以访问和修改该对象的属性来进行通信。