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

相关推荐
weixin_307779132 小时前
C++代码实现MATLAB中的dlarray函数功能
开发语言·c++·算法·matlab
一水鉴天5 小时前
映射、哈希表与哈斯图:计算机科学的三种基线 20261003(元宝)
开发语言·人工智能
Frank_refuel5 小时前
C++11之一场名为“搬家”的 C++ 之旅
开发语言·c++
Wang's Blog6 小时前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
2601_962071576 小时前
类变量和全局变量的查找路径有什么区别?
开发语言·python
\光辉岁月/7 小时前
5.java-数组
java·开发语言
Java后端的Ai之路7 小时前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
谢亮_vipxieliang7 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
时间的拾荒人8 小时前
Qt 多线程详解:从 QThread 到实战
开发语言·qt·面试
郑州光合科技余经理8 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程