首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C 通信模式全景指南:KVO、Notification、Delegation、Block、Target-Action 選型決策

     編輯:關於C語言

五大通信模式對比

模式核心用途耦合度方向負載能力典型場景
KVO屬性變化觀察中(需知對象生命週期)單向屬性值NSOperationQueue 監聽 operation 狀態
Notification廣播消息低(發送/接收雙向解耦)單向任意(userInfo 字典)Core Data 變更通知、跨層級通信
Delegation傳值/傳事件中(協議綁定雙方)雙向任意(協議方法參數)UITableViewDataSource/Delegate、自定義組件回調
Block回調、異步完成低(內聯定義)單向任意(捕獲上下文變量)NSURLSession completionHandler、動畫完成回調
Target-ActionUI 事件響應低(可 nil target 順響應鏈)單向無(僅 selector)UIButton 點擊、手勢識別

決策流程圖(文字版)

需要雙向通信? → 是 → Delegation
否
  需要觀察特定對象屬性變化? → 是 → KVO
  否
    需要廣播給多個不知名接收者? → 是 → Notification
    否
      是 UI 事件(按鈕、手勢)? → 是 → Target-Action
      否
        需要捕獲上下文/異步回調? → 是 → Block
        否 → Delegation (默認選擇)

框架級實例深度剖析

1. KVO:NSOperationQueue 監聽 Operation 狀態

  • Queue 觀察 operation 的 isFinished、isExecuting、isCancelled
  • 屬性變化自動觸發 KVO 通知,Queue 內部調度決策
  • 優勢:無需修改 Operation 代碼,零侵入式監聽

2. Notification:Core Data 變更廣播

  • NSManagedObjectContextDidChangeNotification 攜帶變更對象集合
  • 接收者無需知道發送者,多對多鬆耦合
  • 單向不可回覆,純通知語義

3. Delegation:UITableView 選中回調

  • tableView:didSelectRowAtIndexPath: 傳遞 indexPath 負載
  • Target-Action 無法攜帶自定義數據,故必須用 Delegation
  • 協議定義精確契約,編譯期檢查

4. Block:NSURLSession 異步請求

  • dataTaskWithURL:completionHandler: 內聯處理回調邏輯
  • 調用者不持有 task,task 執行完自動釋放,打破循環引用
  • 注意:捕獲 self 需用 __weak 避免 retain cycle

5. Target-Action:UIButton 點擊

  • 最簡單:[btn addTarget:self action:@selector(tap:) forControlEvents:UIControlEventTouchUpInside]
  • target=nil 時順響應鏈尋找處理者,極致解耦
  • 無負載限制,純事件觸發

Block 循環引用陷阱與解法

危險代碼

manager.complete = ^{
    [manager otherAction]; // 捕獲 manager
    [manager release];
};
// manager → block → manager 循環引用

解法 1:置空打破

manager.complete = ^{
    [manager otherAction];
    manager.complete = nil; // 打破循環
    [manager release];
};

解法 2:weakSelf 模式


__weak typeof(self) weakSelf = self;
manager.complete = ^{
    [weakSelf otherAction];
};

NSOperation 特例

Operation 加入 Queue 後必會執行結束並移出,completionBlock 執行後自動釋放,循環引用臨時存在但必然被打破,相對安全。

演進歷史:NSURLConnection → NSURLSession

  • 早期:NSURLConnection 僅支持 Delegation
  • iOS 5/OS X 10.7:添加 sendAsynchronousRequest:queue:completionHandler:(Block)
  • iOS 7/OS X 10.9:NSURLSession 以 Block 為主流,保留 Delegate 用於進度、認證等高級場景

總結建議

  1. 無標準答案,根據耦合度要求、數據流向、負載類型、生命週期關系綜合判斷
  2. 決策流程圖僅為參考,實際項目中常混合使用
  3. 新代碼優先考慮 Block(簡潔)或 Delegation(契約清晰)
  4. 跨模塊、多對多、無回覆需求 → Notification
  5. 屬性級監聽、零侵入 → KVO
  6. UI 事件、響應鏈 → Target-Action
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved