协议(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】

转载于:https://www.cnblogs.com/xiu619544553/p/5295079.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core 2.2+Quartz.Net 实现Web定时任务

作者&#xff1a;Julian_酱链接&#xff1a;http://www.cnblogs.com/mi12205599/p/10361763.html作为一枚后端程序狗&#xff0c;项目实践常遇到定时任务的工作&#xff0c;最容易想到的的思路就是利用Windows计划任务/wndows service程序/Crontab程序等主机方法在主机上部署定…

lj245a引脚功能图_ULN2003A引脚图及功能-uln2003a原理

ULN是集成达林顿管IC&#xff0c;内部还集成了一个消线圈反电动势的二极管&#xff0c;可用来驱动继电器。它是双列16脚封装,NPN晶体管矩阵,最大驱动电压50V,电流500mA,输入电压5V,适用于TTL COMS,由达林顿管组成驱动电路。ULN是集成达林顿管IC,内部还集成了一个消线圈反电动势…

RocketMQ核心概念

生产者Producer和消费者Consumer NameServer作用 Broker和Topic

交叉编译、软硬链接

什么是交叉编译&#xff1f;交叉编译是一个行为&#xff0c;是在一个平台上生成另一个平台上的可执行代码。 本地编译&#xff1a;本地编译可以理解为&#xff0c;在当前编译平台下&#xff0c;编译出来的程序只能放到当前平台下运行。平时我们常见的软件开发&#xff0c;都是…

扫地机器人狗毛_扫地机器人:我是清理狗毛的!不是清理狗屎的!

原标题&#xff1a;扫地机器人&#xff1a;我是清理狗毛的&#xff01;不是清理狗屎的&#xff01;扫地机器人可以清洁地面和角落里的垃圾&#xff0c;对于满是毛毛的铲屎官家庭来说&#xff0c;简直就是福音呐&#xff01;不过最近&#xff0c;槽点却有点多&#xff1a;家里买…

Linus下安装maven

下载maven安装包 wget http://mirror.bit.edu.cn/apache/maven/binaries/apache-maven-3.2.2-bin.tar.gz 解压 tar -zxvf apache-maven-3.2.2-bin.tar.gz 配置maven环境变量 查看maven解压后安装包目录 vi /etc/profile 进入最底部&#xff0c;按insert,添加环境变量&#x…

linux内核开发基础(linux内核源码、树莓派源码编译、SD卡挂载)

首先下载树莓派linux内核源码&#xff1a; 下载网址&#xff1a;https://github.com/raspberrypi/linux在树莓派使用指令&#xff1a;uname -r查看当前树莓派的版本号&#xff0c;然后选择对应的linux内核版本号进行下载。 将linux内核源码从共享文件夹拷贝到SYSTEM文件夹&am…

Linux实时查看进程命令top笔记

top命令是Linux下常用的性能分析工具&#xff0c;能够实时显示Linux系统中各个进程的资源占用状况&#xff0c;类似于Windows系统的任务管理器功能。 top命令的语法格式&#xff1a; top [-] [d] [p] [q] [c] [C] [S] [s] [n] 常用参数说明 d 指定每两次屏幕信息刷新之间的时间…

C#基础之Equals和Dispose

1.equal()和运算符的区别 由于C#中有值类型和引用类型&#xff0c;那么相等也分为值相等和引用相等。先来看一个值类型简单的例子&#xff0c;顺便也写了string类型的比较。 static void Main(string[] args){int n1 1;int n2 1;Console.WriteLine(n1n2);Console.WriteLine(n…

mysql 时间chuo格式化_Mysql时间戳与时间格式转换问题汇总

一、时间戳的定义时间戳指格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。二、时间格式转时间戳的方法使用unix_timestamp函数&#xff0c;如下&#xff1a;SELECT UNIX_TIMESTAMP();//返回当前时间戳SELECT UNIX_TIMESTAMP(2017-12-16 17:29:56) AS t; //返回指定时…

文件系统(文件系统目录结构、磁盘分区、虚拟文件系统)、linux内核结构框图

什么是文件系统&#xff1f; 常规认知就是根目录下那些文件&#xff0c;但其实并不是那样。文件系统是操作系统用于明确存储设备&#xff08;常见的是磁盘&#xff0c;也有基于NAND Flash的固态硬盘&#xff09;或分区上的文件的方法和数据结构&#xff1b;即在存储设备上组织…

dockerq启动报错(iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9876 -j DNAT --t

docker启动报错 (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9876 -j DNAT --to-destination 172.17.0.2:9876 ! -i docker0: iptables: No chain/target/match by that name. 解决方案&#xff1a;重启docker systemctl restart docker

Linux进程终止命令kill或kill all​笔记

在linux命令下&#xff0c;如果需要终止某个进程&#xff0c;可以使用kill或者killall等命令来实现。终止命令的原理都是向linux内核发送一个系统操作的信号以及某个进程的ID&#xff0c;然后系统内核会根据指定的进程ID进行相应的处理。 kill命令典型的用法&#xff1a;首先使…

linux驱动(驱动编译、字符设备驱动框架、交叉编译树莓派驱动、树莓派驱动本地编译)

什么是驱动&#xff1a; 驱动就是对底层硬件设备的操作进行封装&#xff0c;并向上层提供函数接口。 设备分类&#xff1a; linux系统将设备分为3类&#xff1a;字符设备、块设备、网络设备。 字符设备&#xff1a;指只能一个字节一个字节读写的设备&#xff0c;不能随机读取…

docker启动报错  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9876 -j DNAT --

docker启动报错 : (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9876 -j DNAT --to-destination 172.17.0.2:9876 ! -i docker0: iptables: No chain/target/match by that name. 解决方案&#xff1a; systemctl restart docker

第一个Spark程序

1、Java下Spark开发环境搭建&#xff08;from http://www.cnblogs.com/eczhou/p/5216918.html&#xff09;1.1、jdk安装安装oracle下的jdk&#xff0c;我安装的是jdk 1.7&#xff0c;安装完新建系统环境变量JAVA_HOME&#xff0c;变量值为“C:\Program Files\Java\jdk1.7.0_79”…

arduino判断是否连接串口_Arduino-串口通信

Serial”系列函数&#xff0c;所以我们要对其有所了解&#xff0c;下面介绍几个常“Serial”函数。1、Serial.begin()—设置串行每秒传输数据的速率(波特率)。在同计算机通讯时&#xff0c;使用下面这些值&#xff1a;300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400…

最详细的docker安装rocketMQ教程来了

RocketMQ是一款分布式、队列模型的消息中间件&#xff0c;是由阿里巴巴设计的&#xff0c;具有以下特点&#xff1a; 支持严格的消息顺序 支持Topic与Queue两种模式 亿级消息堆积能力 比较友好的分布式特性 同时支持Push与Pull方式消费消息 历经多次天猫双十一海量消息考验…

树莓派IO口驱动代码的编写、微机总线地址、物理地址、虚拟地址、BCM2835芯片手册

地址总线&#xff1a; 百度百科解释&#xff1a; 地址总线 (Address Bus&#xff1b;又称&#xff1a;位址总线) 属于一种电脑总线 &#xff08;一部份&#xff09;&#xff0c;是由CPU 或有DMA 能力的单元&#xff0c;用来沟通这些单元想要存取&#xff08;读取/写入&#xff…

夺命雷公狗---DEDECMS----26dedecms面包屑导航的实现

我们在很多项目里面都会用到面包屑导航&#xff0c;而dedecms里面也是给我们封装好面包屑导航的了,如下图所示&#xff1a; 在dede里面实现面包屑导航主要用到{dede:field.position/}标签&#xff0c;我们首先来修改下article_movie.htm内容页的模版文件&#xff1a; 我们修改成…