進行 iOS 開發時,經常會反覆遇到 Delegate 模式。
每次使用 UITableView、UITextField 都要加上 delegate,想必你曾想過:「為什麼是 Delegate?不能直接用閉包或通知嗎?」
尤其學到 Observer 模式後,反而更容易混淆。兩者都是「發生事情時通知」的結構,到底差在哪裡?
先說結論。
Delegate 是一個物件將工作委派給唯一一個對象的 1:1 通訊:「這件事交給你。」
Observer 則是多個訂閱者同時訂閱一個事件的 1:N 廣播。
掌握這一句,就已經理解一半了。今天會搭配程式碼把差異說清楚。
什麼是 Delegate 模式?
Delegate 的意思就是「委派」。
把自己不方便處理的工作交給一個可信任的物件:「請你代替我決定。」
用日常生活來比喻如下。
我想預訂餐廳,但懶得親自打電話,所以請一位秘書:「請幫我預訂。」
這位秘書就是 Delegate。委託者一人,受託者也一人,正好是 1:1。
在 Swift 中,會透過協定約定這件事。
// 以協定定義要委派的工作
protocol OrderDelegate: AnyObject {
func didFinishOrder(_ menu: String)
}
class Restaurant {
weak var delegate: OrderDelegate? // 只指定一個對象
func order(_ menu: String) {
delegate?.didFinishOrder(menu) // 只通知那一個對象
}
}
值得注意的是,delegate不是陣列,而是單一的屬性。
既然只交給一個人,當然只會放一個。這就是 Delegate 為 1:1 的原因。
而且還有weak。彼此強參考會形成 retain cycle 並造成記憶體洩漏,因此 Delegate 通常會以 weak 參考持有。
和 Observer 模式有什麼不同?
Observer 就是「觀察者」。
事件發生時,通知會同時送給正在觀察它的多個對象。
繼續用剛才的秘書比喻。
這次我把餐廳開幕消息廣播給整個社區:「今天晚上開幕!」
收聽者可能有十人,也可能有一百人。我不在意誰在聽,只負責廣播出去。
這就是 1:N 廣播,也就是 Observer 模式。
在 iOS 中,NotificationCenter就是代表性的例子。
// 事件發生 → 廣播給所有訂閱者
NotificationCenter.default.post(name: .storeOpen, object: nil)
// 有興趣的物件各自訂閱
NotificationCenter.default.addObserver(
self, selector: #selector(handleOpen),
name: .storeOpen, object: nil)
傳送方不知道接收者是誰,只會加上名稱後送出去。
接收方也由多個物件各自訂閱。
彼此不必知道對方,因此耦合度較低;但缺點是難以追蹤目前誰正在接收通知。
Delegate 與 Observer 一眼比較
只用文字說明容易混淆,所以整理成表格。
| 分類 | Delegate | Observer |
|---|---|---|
| 通訊方式 | 1:1(委派給一人) | 1:N(廣播給多人) |
| 是否知道對方 | 彼此清楚知道 | 彼此不必知道 |
| 代表範例 | UITableViewDelegate | NotificationCenter |
| 回應(回傳值) | 容易接收 | 較難接收 |
| 耦合度 | 相對較高 | 低 |
| 追蹤/除錯 | 容易 | 較困難 |
關鍵在於「是否需要取得回應」。
Delegate 會在你問「這個儲存格要多高?」時回傳數值,是雙向對話的結構。
Observer 只負責送出通知。傳送方不在意誰會如何回應。
那麼什麼時候該用哪個?
這是我實際在專案中使用後整理出的判斷基準。
使用 Delegate 的時機
- 只需要與一個物件溝通時
- 需要從對方取得數值時(例如儲存格數量、高度)
- 畫面轉換等順序與流程明確時
使用 Observer 的時機
- 一個事件需要多個畫面同時反應時
- 登入狀態變更、切換深色模式等全域事件
- 傳送方與接收方不必知道彼此時
例如登入成功後,首頁、我的頁面與頂端橫幅都要同時更新時,用 Delegate 就很吃力。
因為只能委派給一人,若要連接三個地方,程式碼會變得凌亂。
這時用 Observer 廣播一次「登入成功了!」會乾淨得多。
相反地,「按下輸入欄位的確認按鈕」這種 1:1 情境,Delegate 或閉包才是正解。
總結
即使兩者看起來相似,只要想想「要通知幾個人」,就很容易選擇。
一人用 Delegate,多人用 Observer。記住這個基準就夠了。
下次寫程式時試著套用今天學到的內容吧。當只停留在腦中的知識真正融入手感,模式就會變得容易許多。為你加油!

