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;
}

 

posted on 2018-08-07 13:52  低头捡石頭  阅读(37)  评论(0编辑  收藏  举报

导航