Objective-C 类的协议(Protocol)应用:解耦父子类与跨类通信实践

Objective-C 协议(Protocol)应用:解耦父子类与跨类通信实践

在 Objective-C 中,协议(Protocol)是一种强大的解耦工具,特别适用于以下场景:

  1. 解耦父子类继承关系
    避免通过继承强制共享方法实现
  2. 跨类通信
    实现对象间松耦合的交互

一、协议解耦父子类实践

场景:父类需要调用子类特定功能,但不强制所有子类实现

  1. 定义协议

    objectivec 复制代码
    @protocol DataProcessor <NSObject>
    - (NSString *)processData:(NSData *)rawData;
    @optional
    - (void)logProcessingResult;
    @end
  2. 父类使用协议

    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
  3. 子类选择性实现

    objectivec 复制代码
    @interface ImageProcessor : BaseViewController <DataProcessor>
    @end
    
    @implementation ImageProcessor
    - (NSString *)processData:(NSData *)rawData {
        return @"图片处理完成";
    }
    // 可选方法不实现
    @end

优势

  • 子类无需继承无用方法
  • 父类不依赖具体子类实现
  • 支持多态:任意遵守协议的对象都可作为processor

二、跨类通信实践(委托模式)

场景:网络模块完成下载后通知UI更新

  1. 定义通信协议

    objectivec 复制代码
    @protocol DownloadDelegate <NSObject>
    - (void)downloadDidComplete:(NSURL *)filePath;
    - (void)downloadFailedWithError:(NSError *)error;
    @end
  2. 服务类持有委托

    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
  3. 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

三、关键实践原则
  1. 弱引用委托

    始终使用 weak 属性避免循环引用:
    @property (nonatomic, weak) id<MyProtocol> delegate;

  2. 可选方法标记

    @optional 声明非必需方法,调用前检查响应:

    objectivec 复制代码
    if ([delegate respondsToSelector:@selector(optionalMethod)]) {
        [delegate optionalMethod];
    }
  3. 协议组合替代继承

    类可遵循多个协议实现不同能力:

    objectivec 复制代码
    @interface MyClass : NSObject <ProtocolA, ProtocolB>
  4. 类型安全校验

    运行时检查协议一致性:

    objectivec 复制代码
    if ([someObject conformsToProtocol:@protocol(RequiredProtocol)]) {
        // 安全调用
    }

四、优势总结
场景 传统方案问题 协议方案优势
父子类通信 父类需知晓子类具体类型 父类只依赖协议接口
模块间通信 直接引用导致紧耦合 通过委托实现间接松耦合
功能扩展 需修改基类 新增协议不影响现有实现

通过协议实现: $$ \text{解耦度} \propto \frac{1}{\text{类间直接依赖}} $$ 有效降低代码耦合度,提升模块复用性和可测试性。

相关推荐
pe7er2 天前
macOS 应用无法打开(权限问题)解决方案
macos·mac
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1234 天前
matlab画图工具
开发语言·matlab
dustcell.4 天前
haproxy七层代理
java·开发语言·前端
norlan_jame4 天前
C-PHY与D-PHY差异
c语言·开发语言
多恩Stone4 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ4022054964 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
遥遥江上月4 天前
Node.js + Stagehand + Python 部署
开发语言·python·node.js
m0_531237174 天前
C语言-数组练习进阶
c语言·开发语言·算法
Railshiqian4 天前
给android源码下的模拟器添加两个后排屏的修改
android·开发语言·javascript