Objective-C 协议(Protocol)应用:解耦父子类与跨类通信实践
在 Objective-C 中,协议(Protocol)是一种强大的解耦工具,特别适用于以下场景:
- 解耦父子类继承关系
避免通过继承强制共享方法实现 - 跨类通信
实现对象间松耦合的交互
一、协议解耦父子类实践
场景:父类需要调用子类特定功能,但不强制所有子类实现
-
定义协议
objectivec@protocol DataProcessor <NSObject> - (NSString *)processData:(NSData *)rawData; @optional - (void)logProcessingResult; @end -
父类使用协议
objectivec@interface BaseViewController : UIViewController @property (nonatomic, weak) id<DataProcessor> processor; - (void)handleData:(NSData *)data; @end @implementation BaseViewController - (void)handleData:(NSData *)data { if ([self.processor respondsToSelector:@selector(processData:)]) { NSString *result = [self.processor processData:data]; NSLog(@"处理结果: %@", result); // 可选方法检查 if ([self.processor respondsToSelector:@selector(logProcessingResult)]) { [self.processor logProcessingResult]; } } } @end -
子类选择性实现
objectivec@interface ImageProcessor : BaseViewController <DataProcessor> @end @implementation ImageProcessor - (NSString *)processData:(NSData *)rawData { return @"图片处理完成"; } // 可选方法不实现 @end
优势:
- 子类无需继承无用方法
- 父类不依赖具体子类实现
- 支持多态:任意遵守协议的对象都可作为
processor
二、跨类通信实践(委托模式)
场景:网络模块完成下载后通知UI更新
-
定义通信协议
objectivec@protocol DownloadDelegate <NSObject> - (void)downloadDidComplete:(NSURL *)filePath; - (void)downloadFailedWithError:(NSError *)error; @end -
服务类持有委托
objectivec@interface DownloadManager : NSObject @property (nonatomic, weak) id<DownloadDelegate> delegate; - (void)startDownload:(NSURL *)url; @end @implementation DownloadManager - (void)startDownload:(NSURL *)url { // 模拟下载完成 [self.delegate downloadDidComplete:url]; } @end -
UI类实现协议
objectivec@interface ProfileViewController : UIViewController <DownloadDelegate> @property (nonatomic, strong) DownloadManager *downloader; @end @implementation ProfileViewController - (void)viewDidLoad { [super viewDidLoad]; self.downloader = [DownloadManager new]; self.downloader.delegate = self; // 建立连接 [self.downloader startDownload:[NSURL URLWithString:@"https://example.com/avatar.jpg"]]; } #pragma mark - DownloadDelegate - (void)downloadDidComplete:(NSURL *)filePath { [self updateAvatarWithImage:[UIImage imageWithContentsOfFile:filePath.path]]; } @end
三、关键实践原则
-
弱引用委托
始终使用
weak属性避免循环引用:
@property (nonatomic, weak) id<MyProtocol> delegate; -
可选方法标记
用
@optional声明非必需方法,调用前检查响应:objectivecif ([delegate respondsToSelector:@selector(optionalMethod)]) { [delegate optionalMethod]; } -
协议组合替代继承
类可遵循多个协议实现不同能力:
objectivec@interface MyClass : NSObject <ProtocolA, ProtocolB> -
类型安全校验
运行时检查协议一致性:
objectivecif ([someObject conformsToProtocol:@protocol(RequiredProtocol)]) { // 安全调用 }
四、优势总结
| 场景 | 传统方案问题 | 协议方案优势 |
|---|---|---|
| 父子类通信 | 父类需知晓子类具体类型 | 父类只依赖协议接口 |
| 模块间通信 | 直接引用导致紧耦合 | 通过委托实现间接松耦合 |
| 功能扩展 | 需修改基类 | 新增协议不影响现有实现 |
通过协议实现: $$ \text{解耦度} \propto \frac{1}{\text{类间直接依赖}} $$ 有效降低代码耦合度,提升模块复用性和可测试性。