將特定功能委託給外部對象實現。組件定義協議規定委托人需實現的方法,使用者遵守協議並設置為委托人。實現組件與業務邏輯解耦。
// 協議:定義委托人需具備的能力 @protocol CompanyProtocol- (void)doIPO; @end // 公司類:持有委托人引用 @interface Company : NSObject @property (nonatomic, strong) id agent; // 委托人 - (void)startIPO; @end @implementation Company - (void)startIPO { if (self.agent) [self.agent doIPO]; // 委托執行 } @end // 財務顧問:遵守協議實現具體操作 @interface FinanceAdvisor : NSObject @end @implementation FinanceAdvisor - (void)doIPO { NSLog(@"開始上市流程..."); } @end // 使用 FinanceAdvisor *advisor = [[FinanceAdvisor alloc] init]; Company *company = [[Company alloc] init]; company.agent = advisor; [company startIPO]; // 實際調用advisor的doIPO
@protocol SwitchDelegate// 狀態改變回調,攜帶新狀態參數 - (void)switchDidChangeState:(Switch *)switch newState:(SwitchState)state; @end @interface Switch : NSObject @property (nonatomic, assign, readonly) SwitchState currentState; @property (nonatomic, weak) id delegate; // weak避免循環引用 @end
@interface Room : NSObject@property (strong, nonatomic) Light *light; @property (strong, nonatomic) Switch *switch; @end @implementation Room - (instancetype)init { self = [super init]; if (self) { self.light = [[Light alloc] init]; self.switch = [[Switch alloc] init]; self.switch.delegate = self; // 自己作為委托人 } return self; } // 實現委托方法 - (void)switchDidChangeState:(Switch *)sender newState:(SwitchState)state { if (state == SwitchStateOff) [self.light turnOff]; else [self.light turnOn]; } @end
| 維度 | Target-Action | Delegate委托 |
|---|---|---|
| 綁定對象 | 任意target + 任意selector | 遵守協議的delegate對象 |
| 方法定義 | 調用者自定義 | 組件預先在協議中聲明 |
| 參數傳遞 | 通常僅sender | 協議定義,可攜帶豐富上下文 |
| 多實例區分 | 需在action內判斷sender | 同樣需判斷,但協議可設計多方法 |
| 類型安全 | 運行時檢查 | 編譯期檢查(協議遵守) |
| 適用組件 | 簡單控件(按鈕、開關) | 複雜組件(表視圖、網絡層、文本輸入) |
痛點:一個類作為多個同類組件委托時,所有回調進入同一方法,需通過sender判斷來源,代碼分散。
Block優勢:每個組件設置獨立Block回調,邏輯內聯,天然隔離(詳見《Objective-C Block回調機制》)。
weak防止循環引用以便使用respondsToSelector:安全調用可選方法組件名+動作+上下文,如tableView:didSelectRowAtIndexPath:@optional標記,調用前檢查[delegate respondsToSelector:@selector(...)]