OC语言 - 协议 | 代理
■ 协议
Protocol 用来声明一大堆的方法,不能声明成员变量,不能写实现。协议本身一般写在 .h 头文件中,但也可以定义在外边单独的文件中
OC 虽然不能继承多个类,但是能够遵守多个协议。只要父类遵守了某个协议,那么子类同样遵守;协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明
协议的作用
1. 可以将业务中的方法定义剥离出来,形成一个单独的文件
2. 如果需两个系统需要数据交互,可以制定一套双方都遵循的协议,然后把相应的协议文件添加进两个系统所需的项目中实现即可。至于这一点,非正式协议就做不到
注:在 iOS 2 之前是没有引入协议的,实现协议主要是通过给 NSObject 添加 Category 类别扩展,这种方式相对于后来引入的协议来说就叫做非正式协议。非正式协议都是以 NSObject 的 Category 的方式实现的,就是说所有基于 NSObject 的子类都可以使用定义的非正式协议。对于协议来说编译器会在编译期检查语法错误,而非正式协议则不会检查是否实现
关键字:required 默认要求实现,若没有实现则出现警告但并不会报错;optional 可选实现
■ 代理
代码示例:代理通常和协议一同使用!下面代码中,在 Girl 中声明婚前协议(接口);在 Boy 中遵循协议并实现协议所声明的方法(实现)
// - Girl.h
1 #import <Foundation/Foundation.h> 2 3 @protocol BeforeMarriedProtocol <NSObject>// 声明协议 4 5 @required 6 - (void)doCook:(NSString *)foodName; 7 - (BOOL)doHousework; 8 @optional 9 - (void)driveCar; 10 11 @end 12 13 @interface Girl : NSObject 14 15 @property(nonatomic, assign)id <BeforeMarriedProtocol> delegate;// 代理一般同协议配合使用 16 -(void)hungry:(NSString *)someFood; 17 18 @end
// - Girl.m
1 #import "Girl.h" 2 3 @implementation Girl 4 5 -(void)hungry:(NSString *)someFood{ 6 // 安全保障机制:如果代理响应了方法 7 if ([_delegate respondsToSelector:@selector(doHousework)]) { 8 BOOL result = [_delegate doHousework]; 9 10 if (result) { 11 12 NSLog(@"家务已经干完,继续做吃的%@",someFood); 13 if ([_delegate respondsToSelector:@selector(doCook:)]) { 14 [_delegate doCook:someFood]; 15 } 16 }else{ 17 18 NSLog(@"家务还没有做完,接着干!"); 19 } 20 } 21 } 22 23 @end
// - Boy.h
1 #import <Foundation/Foundation.h> 2 #import "Girl.h" 3 @interface Boy : NSObject <BeforeMarriedProtocol>// 遵循协议 4 5 - (void)doCook:(NSString *)foodName; 6 - (BOOL)doHousework; 7 8 @end
// - Boy.m
1 #import "Boy.h" 2 3 @implementation Boy 4 5 - (void)doCook:(NSString *)foodName{ 6 7 NSLog(@"%@已做好,请享用",foodName); 8 } 9 - (BOOL)doHousework{ 10 int n = 0; 11 n = arc4random()%10; 12 if (n % 2 ==0) { 13 14 return YES; 15 } 16 return NO; 17 } 18 19 @end
// - main.m
#import <Foundation/Foundation.h> #import "Girl.h" #import "Boy.h" int main(int argc, const char * argv[]) { @autoreleasepool { Girl *girl = [[Girl alloc] init]; Boy *boy = [[Boy alloc] init]; girl.delegate = boy;// 指定代理 [girl hungry:@"红烧鱼"]; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律