通知模式
Swift 裡面有哪些常見的「通知/模式(pattern)」可以用來讓不同物件互相溝通, 在 iOS / macOS 的 Swift 開發裡,確實有幾種常見的「設計模式」或「資料傳遞方式」,NotificationCenter 就是其中一種。
以下整理幾個常見的 Swift 資料傳遞 / 溝通模式:
1. NotificationCenter
-
一對多的廣播模式(Publish/Subscribe)
-
適合「全域事件」的傳遞,不用物件之間互 相持有。
-
範例:
// 發送通知
NotificationCenter.default.post(name: .myEvent, object: nil)
// 監聽通知
NotificationCenter.default.addObserver(
self, selector: #selector(handleEvent),
name: .myEvent, object: nil
)
@objc func handleEvent() {
print("收到通知")
}
extension Notification.Name {
static let myEvent = Notification.Name("myEvent")
}
2. Delegate Pattern
-
一對一的回調(callback)
-
常用在 UIKit / SwiftUI(例如
UITableViewDelegate) -
範例:
protocol MyDelegate: AnyObject {
func didTapButton()
}
class Child {
weak var delegate: MyDelegate?
func tap() {
delegate?.didTapButton()
}
}
class Parent: MyDelegate {
let child = Child()
init() {
child.delegate = self
}
func didTapButton() {
print("Button tapped")
}
}
因為 delegate 實在太重要了,所以特別在拉一篇文章出來說。 Swift Delegate(委派模式)
3. Closure Callback
-
使用閉包傳遞資料或回調
-
輕量,適合短期、局部的事件
-
範例:
class Worker {
func doWork(completion: (String) -> Void) {
completion("工作完成")
}
}
let worker = Worker()
worker.doWork { result in
print(result)
}
4. Combine / Swift Concurrency (async/await)
-
Apple 推出的新一代反應式編程
-
適合「資料流」或「連續事件」的觀察
-
範例(Combine):
import Combine
class ViewModel {
@Published var name: String = ""
}
let vm = ViewModel()
let cancellable = vm.$name.sink { newName in
print("名字更新: \(newName)")
}
vm.name = "Thomas" -
範例(async/await + AsyncStream):
func fetchData() async -> String {
return "Hello"
}
Task {
let result = await fetchData()
print(result)
}
5. Key-Value Observing (KVO) (舊方法)
- 適合監聽屬性變化(常見於 ObjC 遺產)
- Swift 原生比較少用,建議用
@Published或 Combine 替代。
🔑 總結:
- 一對多、全域事件 →
NotificationCenter - 一對一、明確回調 → Delegate
- 輕量回調 → Closure
- 資料流 / 狀態綁定 → Combine / async-await
- 舊屬性監聽 → KVO
太好了 👍 我幫你整理了一個 Swift 常見溝通方式的比較表,讓你一眼看懂 NotificationCenter 跟其他 pattern 的差別:
📊 Swift 資料傳遞/事件處理方式比較
| 模式 | 特性 | 使用情境 | 優點 | 缺點 |
|---|---|---|---|---|
| NotificationCenter | 一對多(廣播) | 系統廣播事件(鍵盤彈出、app 進入背景)、多個模組要同時收到事件 | 全域共享,不需要物件間參考 | 難以追蹤來源、型別安全差 |
| Delegate | 一對一(回調介面) | UITableViewDelegate、UITextFieldDelegate、子物件回報父物件事件 | 清楚、型別安全、結構化 | 只能一對一,物件間耦合較強 |
| Closure Callback | 一對一(inline 回調) | 輕量操作(例如網路請求完成後回傳結果) | 簡潔,不需要額外 protocol | callback 地獄(多層巢狀)、生命週期管理要小心 |
| Combine / @Published | 多對多(響應式資料流) | ViewModel 與 UI 綁定、持續監聽值變化 | 現代、型別安全、易於組合 | 需要 iOS 13+,學習曲線較高 |
| KVO | 一對多(舊屬性監聽) | 舊版 Objective-C API(如 AVPlayer.status) | 系統框架支援 | 寫法冗長,不直觀,Swift 原生少用 |
📌 流程圖範例
事件來源(Sender)
│
┌─────┼───────────────────┐
│ │ │
▼ ▼ ▼
Delegate(單一回調) NotificationCenter(廣播)
Closure Callback(inline) Combine(資料流持續監聽)
👉 簡單記:
- 全域廣播 → NotificationCenter
- 一對一明確責任 → Delegate
- 輕量回調 → Closure
- 狀態綁定 / 連續事件 → Combine