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{类间直接依赖}} $$ 有效降低代码耦合度,提升模块复用性和可测试性。