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

相关推荐
陪我去看海5 小时前
受够了 AI 写完代码留下一堆端口?我做了一个端口管理App!
前端·macos·vibecoding
cui_ruicheng5 小时前
Python从入门到实战(六):非序列容器
开发语言·python
西西学代码5 小时前
Flutter---底部导航栏(2)
开发语言·javascript·flutter
legendary_1635 小时前
SINK芯片:Type-C统一供电时代的小家电核心方案
c语言·开发语言·人工智能·智能手机
momo5 小时前
JAVA基础知识
java·开发语言
发光的沙子6 小时前
FPGA----配置根文件系统ip和mac地址
网络协议·tcp/ip·macos
xxie1237946 小时前
Python装饰器与语法糖
开发语言·python
郑州光合科技余经理7 小时前
海外外卖平台源码改造实战——多语言核心代码实现
java·开发语言·前端·后端·mysql·架构·php
凯瑟琳.奥古斯特7 小时前
力扣1012数位DP解法详解
开发语言·c++·算法·leetcode·职场和发展
Railshiqian7 小时前
UserPickerActivity 内部逻辑分析
开发语言·python