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

相关推荐
csbysj20201 小时前
CSS 网格元素
开发语言
lly2024061 小时前
DOM 元素:深入理解与高效运用
开发语言
鸟儿不吃草1 小时前
安卓实现左右布局聊天界面
android·开发语言·python
李老师的Java笔记1 小时前
如何解决Mac升级完nodejs没有生效的问题?
macos
曦夜日长1 小时前
C++ STL容器string(一):string的变量细节、默认函数的认识以及常用接口的使用
java·开发语言·c++
代码中介商1 小时前
C++ STL 标准模板库完全指南:从容器到迭代器
开发语言·c++·stl
winner88812 小时前
C++ 构造函数、析构函数、虚函数、虚析构
开发语言·c++
北山有鸟2 小时前
IS_ERR 判断出错后,再用 PTR_ERR 把它强制转换回 int 型的错误码作为函数的返回值。
java·开发语言
开开心心_Every2 小时前
轻量级PDF阅读器,仅几M大小打开秒开
linux·运维·服务器·安全·macos·pdf·phpstorm
格林威2 小时前
工业视觉检测:提供可视化UI调试工具的实现方式是什么?
开发语言·人工智能·数码相机·ui·计算机视觉·视觉检测·工业相机