协议(Protocol)与委托代理(Delegate)

Posted Kingdev

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了协议(Protocol)与委托代理(Delegate)相关的知识,希望对你有一定的参考价值。

协议(Protocol)的作用:

1. 规范接口,用来定义一套公用的接口;

2. 约束或筛选对象。

 

代理(Delegate):

它本身是一种设计模式,委托一个对象<遵守协议>去做某件事情,目的是为了降低对象间的耦合度;或用来逆向传值。

 

一、定义一套公用接口

 1 /** 协议 */
 2 @protocol ExecuteProtocol <NSObject>
 3 
 4 @required
 5 /**
 6  *  @brief 必须实现的某个方法
 7  */
 8 - (NSUInteger)qualified;
 9 
10 
11 @optional
12 /**
13  *  @brief 可选的方法
14  */
15 - (void)doSomething;
16 
17 @end

协议只有.h文件,没有.m文件。因为 Protocol 仅定义公用的一套接口,并不能提供具体的实现方法。(具体的实现需要某个遵守了协议的类去实现,然后该类就可以作为被筛选出来的对象做些事情,后面会讲到)

 

假如控制器里面需要用到协议,那么导入协议:

 1 #import "ExecuteProtocol.h" 

并且实现协议的 required 方法(否则编译器会warning)

 

ViewController的代码如下:

 1 #import "ViewController.h"
 2 #import "ExecuteProtocol.h"
 3 #import "Object.h"
 4 
 5 @interface ViewController ()
 6 @property (nonatomic, strong) UILabel *label;
 7 @end
 8 
 9 @implementation ViewController
10 
11 #pragma mark - View lifeCycle
12 - (void)viewDidLoad {
13     [super viewDidLoad];
14     [self.view addSubview:self.label];
15     [self getHouse:[[Object alloc] init]];
16 }
17 
18 - (void)getHouse:(id <ExecuteProtocol>)obj {
19     self.label.text = [NSString stringWithFormat:@"%lu", [obj qualified]];
20 }
21 
22 #pragma mark - getter Methods
23 - (UILabel *)label {
24     if (!_label) {
25         _label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
26         _label.textAlignment = NSTextAlignmentCenter;
27         _label.backgroundColor = [UIColor redColor];
28     }
29     return _label;
30 }
31 @end

在控制器里面添加一个方法,这个方法的参数必须是遵守了协议的某个对象,所以创建了Object对象:

1 #import <Foundation/Foundation.h>
2 #import "ExecuteProtocol.h"
3 
4 /** 某对象 */
5 @interface Object : NSObject <ExecuteProtocol>
6 
7 @end

并且实现协议方法:

1 #import "Object.h"
2 
3 @implementation Object
4 
5 - (NSUInteger)qualified {
6     return 88;
7 }
8 
9 @end

简单的小Demo。

 

二、代理传值(SecondaryViewController 传值到 ViewController中)

1.在ViewController中

1 // ViewController需要 遵守代理
2 @interface ViewController () <SecondaryViewControllerDelegate>
3 
4  SecondaryViewController *secVC = [[SecondaryViewController alloc] init];
5  // 指定代理
6  secVC.delegate = self;
7  [self.navigationController pushViewController:secVC animated:YES];

1 // 实现required代理方法,实现传值,打印结果
2 #pragma mark - SecondaryViewControllerDelegate Methods
3 - (void)controller:(SecondaryViewController *)controller text:(NSString *)text {
4     NSLog(@"%@ %@", controller, text);
5 }

 

2.在SecondaryViewController中

1)首先,声明代理

 1 #import <UIKit/UIKit.h>
 2 @class SecondaryViewController;
 3 
 4 /**
 5  *  @brief 协议方法(类名+Delegate)
 6  */
 7 @protocol SecondaryViewControllerDelegate <NSObject>
 8 @required
 9 /**
10  *  @brief 传值
11  *
12  *  @param controller 当前控制器
13  *  @param text       文本值
14  */
15 - (void)controller:(SecondaryViewController *)controller text:(NSString *)text;
16 @end
17 
18 @interface SecondaryViewController : UIViewController
19 /**
20  *  @brief 代理用weak修饰(防止内存泄露)
21  */
22 @property (nonatomic, weak) id <SecondaryViewControllerDelegate> delegate;
23 @end

2)判断代理存在与否和方法是否响应

 1 /** 
 2  * SecondaryViewController
 3  */
 4 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
 5     /**
 6      *  @brief 判断是否设置了代理并且代理是否响应了代理方法
 7      */
 8     if (self.delegate && [self.delegate respondsToSelector:@selector(controller:text:)]) {
 9         [self.delegate controller:self text:@"传值"];
10     }
11     [self.navigationController popViewControllerAnimated:YES];
12 }

源码:戳这里

尊重作者劳动成果,转载请注明: 【kingdev】

以上是关于协议(Protocol)与委托代理(Delegate)的主要内容,如果未能解决你的问题,请参考以下文章

【iOS】协议(Protocol)和代理(Delegate)

Protocol, Delegate

@protocol(协议)和@delegate(代理)的个人理解 通俗易懂

iOS 代理协议

iOS常用设计模式和机制之代理

iOS 代理设计模式