Protocol 核心概念
Protocol 定義一組方法聲明,任意類可選擇實現。類似 Java Interface、C++ 純虛類。核心用途:**代理模式** 解耦調用者與實現者。
聲明與實現語法
協議聲明
@protocol ButtonDelegate
- (void)onClick:(Button*)button;
@optional
- (void)onLongPress:(Button*)button;
@required
- (void)onDoubleClick:(Button*)button;
@end
- 繼承
NSObject 協議可用 respondsToSelector:
@optional 可選實現 (默認),@required 必須實現
類聲明遵循協議
@interface ButtonListener : NSObject
@end
@implementation ButtonListener
- (void)onClick:(Button*)button { NSLog(@"Clicked!"); }
- (void)onDoubleClick:(Button*)button { NSLog(@"Double!"); }
// onLongPress 可選,不實現也編譯通過
@end
代理模式完整實戰:Button 與 Listener
Button.h
#import
@class Button; // 前向聲明
@protocol ButtonDelegate
- (void)onClick:(Button*)button;
@end
@interface Button : NSObject
@property (nonatomic, weak) id delegate; // weak 避免循環引用
- (void)click;
@end
Button.m
#import "Button.h"
@implementation Button
- (void)click {
NSLog(@"Button clicked");
if ([_delegate respondsToSelector:@selector(onClick:)]) {
[_delegate onClick:self];
}
}
@end
ButtonListener.h
#import
@protocol ButtonDelegate; // 協議前向聲明
#import "Button.h"
@interface ButtonListener : NSObject
@end
ButtonListener.m
#import "ButtonListener.h"
@implementation ButtonListener
- (void)onClick:(Button*)button {
NSLog(@"Listener received click from %@", button);
}
@end
Main.m 使用
int main() {
@autoreleasepool {
Button *btn = [[Button alloc] init];
ButtonListener *listener = [[ButtonListener alloc] init];
btn.delegate = listener;
[btn click]; // 輸出: Button clicked → Listener received click...
}
return 0;
}
關鍵設計點
| 要點 | 說明 |
| delegate 用 weak | 避免 Button 持有 Listener、Listener 持有 Button 形成循環引用 |
| 調用前判斷 respondsToSelector | 協議方法可能 @optional,防止未實現崩潰 |
| 傳遞 self 給代理 | 代理需知曉是哪個 Button 觸發 |
| 協議繼承 NSObject | 獲得 respondsToSelector 等基礎方法 |
iOS 系統框架中的代理應用
UITableViewDelegate / UITableViewDataSource
UIScrollViewDelegate
UITextFieldDelegate
CLLocationManagerDelegate
NSURLSessionDelegate
所有遵循統一模式:View 持有 weak delegate,事件發生時回調 delegate 方法,Controller 實現協議處理業務邏輯。
Protocol 進階特性
- 屬性聲明:
@property (readonly) NSString *name; 要求實現者提供 getter
- 類方法:
+ (instancetype)sharedInstance;
- 協議合成:
@protocol MyProtocol
- 運行時檢查:
[obj conformsToProtocol:@protocol(ButtonDelegate)]
Protocol vs Category vs Inheritance
| 機制 | 用途 | 耦合度 | 多實現 |
| 繼承 | is-a 關係、代碼復用 | 高 (強耦合) | 單繼承 |
| Category | 擴展現有類方法 | 中 (編譯時) | 可多 Category |
| Protocol | 定義接口規範、代理 | 低 (運行時) | 可遵循多協議 |
總結
Protocol 是 Objective-C 實現「面向接口編程」的核心機制。配合代理模式,實現了 View 與 Controller 的完全解耦,是 Cocoa Touch 架構的基石。掌握 weak delegate、respondsToSelector 防崩、協議繼承 NSObject、可選/必選方法聲明,是 iOS 開發必備基本功。
- 上一篇文章: C語言核心知識點總結:從基礎語法到進階技巧速查表
- 下一篇文章: Objective-C Category (分類) 完整指南:動態擴展類方法的實戰技巧
Copyright ©
程式碼之家 All Rights Reserved