Skip to main content

通知模式

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一對一(回調介面)UITableViewDelegateUITextFieldDelegate、子物件回報父物件事件清楚、型別安全、結構化只能一對一,物件間耦合較強
Closure Callback一對一(inline 回調)輕量操作(例如網路請求完成後回傳結果)簡潔,不需要額外 protocolcallback 地獄(多層巢狀)、生命週期管理要小心
Combine / @Published多對多(響應式資料流)ViewModel 與 UI 綁定、持續監聽值變化現代、型別安全、易於組合需要 iOS 13+,學習曲線較高
KVO一對多(舊屬性監聽)舊版 Objective-C API(如 AVPlayer.status系統框架支援寫法冗長,不直觀,Swift 原生少用

📌 流程圖範例

事件來源(Sender)

┌─────┼───────────────────┐
│ │ │
▼ ▼ ▼
Delegate(單一回調) NotificationCenter(廣播)
Closure Callback(inline) Combine(資料流持續監聽)

👉 簡單記:

  • 全域廣播 → NotificationCenter
  • 一對一明確責任 → Delegate
  • 輕量回調 → Closure
  • 狀態綁定 / 連續事件 → Combine