iOS 开发:Objective-C 之分类及协议

在 Objective-C 中,分类 (Category)协议 (Protocol) 是实现代码解耦、扩展功能和组件化开发的核心工具。


一、 分类 (Category)

分类 允许你在不修改原始类代码、不使用继承的情况下,动态地为现有的类添加新方法。

1. 核心作用

  • 扩展系统类 :给 NSString, NSArray 等添加自定义工具方法。
  • 分解大型类 :将一个庞大的 .m 文件按功能拆分成多个小文件(如 User+Login.m, User+Profile.m)。

2. 代码案例:给 NSString 增加一个校验邮箱的功能

NSString+Email.h (声明)

objectivec 复制代码
#import <Foundation/Foundation.h>

@interface NSString (Email)
// 声明一个新方法
- (BOOL)isEmailFormat;
@end

NSString+Email.m (实现)

objectivec 复制代码
#import "NSString+Email.h"

@implementation NSString (Email)
- (BOOL)isEmailFormat {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:self];
}
@end

使用方法:

objectivec 复制代码
#import "NSString+Email.h"

NSString *myMail = @"test@example.com";
if ([myMail isEmailFormat]) {
    NSLog(@"这是一个有效的邮箱");
}

3. 注意事项

  • 只能添加方法,不能添加成员变量(可以通过"关联对象"实现,但属于进阶内容)。
  • 方法覆盖 :如果分类中的方法名与原类重复,分类的方法会"覆盖"原类。建议分类方法名加上前缀(如 my_isEmailFormat)。

二、 协议 (Protocol)

协议 定义了一套方法列表,但不负责实现。任何类都可以声明"遵守"这个协议并实现其中的方法。它类似于 Java 或 C# 中的 Interface(接口)

1. 核心关键字

  • @required必须实现的方法(默认)。
  • @optional可选实现的方法。

2. 代码案例:定义一个"管家"协议

HouseKeeperProtocol.h

objectivec 复制代码
#import <Foundation/Foundation.h>

@protocol HouseKeeperProtocol <NSObject>

@required
- (void)cleanRoom; // 必须打扫房间

@optional
- (void)cookDinner; // 可以选择是否做饭

@end

Person.h (类声明遵守协议)

objectivec 复制代码
#import "HouseKeeperProtocol.h"

// 在类名后用 <> 表示遵守协议
@interface Person : NSObject <HouseKeeperProtocol>
@end

Person.m (实现协议方法)

objectivec 复制代码
@implementation Person

- (void)cleanRoom {
    NSLog(@"正在用吸尘器打扫...");
}

// cookDinner 是可选的,可以不写
@end

三、 协议的高级用法:委托模式 (Delegate)

这是协议在 iOS 开发中最常用的场景(如 TableView 的点击事件)。

objectivec 复制代码
// 1. 定义协议
@protocol DownloadDelegate <NSObject>
- (void)downloadDidFinish:(NSString *)filePath;
@end

// 2. 在下载器类中定义 delegate 属性
@interface Downloader : NSObject
@property (nonatomic, weak) id<DownloadDelegate> delegate; 
- (void)start;
@end

@implementation Downloader
- (void)start {
    NSLog(@"下载中...");
    // 3. 通知代理对象
    if ([self.delegate respondsToSelector:@selector(downloadDidFinish:)]) {
        [self.delegate downloadDidFinish:@"/path/to/file"];
    }
}
@end

四、 分类 vs 协议:怎么选?

特性 分类 (Category) 协议 (Protocol)
主要目的 扩展:给现有类增加功能 规范:定义一套行为准则
方法实现 必须在分类的 .m 中实现 协议本身不实现,由遵守它的类实现
状态存储 不允许添加成员变量 不涉及变量,只涉及方法
使用场景 比如想给所有 UIButton 加一个抖动动画 比如定义"凡是能飞的物体(鸟、飞机)都要有 fly 方法"

总结

  • 如果你想让某个现有的类"更强大 ",用 Category
  • 如果你想让不同的类"遵守同一种约定 "或者实现"回调通知 ",用 Protocol
相关推荐
AI云海1 天前
iOS 多 Target 打包、UAT/生产测试与上架 App Store 全流程指南
ios
阿里超级工程师1 天前
最新快速申请ios打包证书和profile文件步骤
ios·打包证书
2501_915909061 天前
iOS 应用反调试技详解术 检测调试器的原理与防护实践
android·ios·小程序·https·uni-app·iphone·webview
游戏开发爱好者81 天前
TraceEagle 代理抓包详解,无感代理、去证书绑定与 HTTP/3 解密能力解析
网络协议·计算机网络·网络安全·ios·adb·https·udp
aiopencode1 天前
SwiftUI Introspect生产环境完全指南:为什么它是安全可靠的选择
后端·ios
for_ever_love__1 天前
iOS: 网络管理单例
学习·ios·objective-c
00后程序员张1 天前
iOS加固技术路线全面解析:Bitcode模式、源码模式与汇编模式对比及爱加密优势
android·汇编·ios·小程序·uni-app·cocoa·iphone
ii_best2 天前
更新!移动端开发软件按键安卓版&手机助手v5.1.0上线!本地AI识别全面解锁,脚本开发再升级
android·人工智能·ios·按键精灵
weixin_403810132 天前
03-iOS免越狱无线投屏-上传图片和视频到相册
ios·新媒体运营·跨境电商·ios自动化·ios投屏·ios智能体·ios脚本
2501_916007472 天前
SwiftUI 声明式语法与 Xcode 预览功能详解
ide·vscode·ios·swiftui·个人开发·xcode·敏捷流程