iOS 开发-Objective-c基础:协议和代理delegate&protocol)

写在前面的话

在我身边的同学中,有一些同学不能正确的理解什么是协议和代理,协议和代理的关系。这篇博文总结了一些我对协议和代理的理解,这是对自己所学习的知识的一个总结,可能存在一些理解不到位的地方,请多多包涵,同时也希望这些文字能帮到一些人。

什么是协议和代理

接触过Java的同学可能会知道在Java中有一种和协议代理很相似的东西,叫做接口(interface)如果你对它有一定了解,那么学习协议和代理也会很轻松。

公司和程序员

做一个也许不是很恰当的比喻,协议就像合同,代理就是执行合同内容的人。

下面,我们来看一个故事:

有一家公司招聘了一名程序员张三,和张三签订了一份劳动合同,合同里规定了他需要完成的工作,在公司需要的时候,张三就必须完成这些工作,有时候还需要将结果反馈给公司。

在上面的故事中一共有四个关键点,我们来梳理一下。

  1. 有一家公司。
  2. 公司提供了一个程序员的职位。
  3. 来应聘这个职位的人必须签订程序员的劳动合同,并完成合同所规定的工作。
  4. 张三应聘上了这个职位。

类比到OC中。
这里的公司就是定义协议的类,程序员职位就是代理,劳动合同就是它定义的协议,程序员必须完成的工作是协议里规定的必须实现的方法,张三就是实现这个协议的类,张三应聘上了这个职位就是设置好了代理。

举个栗子

听完了故事,接下来就来实践一下吧
首先创建一个CommandLine Tool 工程,并创建Company 和Person两个类,它们都继承自NSObject
文件列表
然后我们在Company.h 文件中声明一个协议(故事中的劳动合同)

#import <Foundation/Foundation.h>

//声明协议内容
@protocol CompanyProgrammerDelegate <NSObject>

@required//必须的
-(NSString *)doProgrammingJobWithProjectName:(NSString *)name;//根据工程的名称来完成编程工作
@optional//可选的
-(void)repairComputer;//修电脑
@end

@interface Company : NSObject
@property(nonatomic,weak)id <CompanyProgrammerDelegate> programer;//代理
-(void)doWork;//开始工作
@end

上面的代码声明了一个叫做CompanyProgrammerDelegate的协议,协议规定了实现协议的类必须完成以下要求:

  • 实现一个叫做doProgrammingJobWithProjectName:的方法
  • 可以选择性实现一个叫做repairComputer的方法(不是必须的,也可以不实现)

同时,我们也在Company类的interface里声明了一个叫programmer的属性,这就是我们常说的代理(公司提供的程序员职位):

@property(nonatomic,weak)id <CompanyProgrammerDelegate> programer;//代理

其中id 后面的尖括号指定了这个属性必须是实现了CompanyProgrammerDelegate协议的(必须能够完成程序员该做的工作的,签订了劳动合同的人才能在这个职位工作)。

我们也声明了一个方法表示公司开始工作。

-(void)doWork;//开始工作

然后在Company.m中实现这个方法:

-(void)doWork{

  NSLog(@"开始工作");
    if (self.programer){//检查代理是否已经设置(该职位是否有人)
        if([self.programer respondsToSelector:@selector(doProgrammingJobWithProjectName:)])
        {//如果已经设置,代理能否响应相应的方法(如果有人,这个人是不是遵守了合同,能不能完成相应的工作)
            NSString * completed = [self.programer doProgrammingJobWithProjectName:@"测试工程"];
            //调用代理的方法,并获得返回值。(让程序员完成他的工作,并得到结果)
            NSLog(@"%@",completed);
            //输出结果。
        }
        if([self.programer respondsToSelector:@selector(repairComputer)])
        {//检查代理是否实现了可选的方法,如果实现了,则调用。
            [self.programer repairComputer];
        }
    }    
    NSLog(@"工作结束");
}

好了公司有了,合同有了,职位也有了,就差一个程序员了。

接下来我们在person类中实现上面声明的协议。
在Person.h中:

#import <Foundation/Foundation.h>
#import "Company.h"//导入协议所在的头文件

@interface Person : NSObject<CompanyProgrammerDelegate>//声明将要实现的协议

@end

在Person.m中:

#import "Person.h"

@implementation Person
//实现协议中规定的必须实现的方法
-(NSString *)doProgrammingJobWithProjectName:(NSString *)name{
    NSLog(@"我在编程,工程名字叫:%@",name);//完成一些工作
    return [NSString stringWithFormat:@"[%@] 完成了",name];//将结果返回给调用者
}

//实现协议中规定的可选实现的方法,因为是可选的,也可以不实现。
-(void)repairComputer{
    NSLog(@"我在修电脑");
}
@end

现在一切准备就绪,接下来在main.m里实例化他们:

#import <Foundation/Foundation.h>
#import "Company.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {

        Person * zhangSan = [[Person alloc]init];
        Company * aCompany = [[Company alloc]init];

        aCompany.programer = zhangSan;//设置代理(张三应聘上了程序员职位)
        [aCompany doWork];//开始工作

    }
    return 0;
}

运行的结果:

运行结果

最后

总的来说,A把自己需要做但不能由自己完成的事情写到协议中,如果B实现了(或者叫遵守了)这个协议,就必须完成协议里规定的内容,当A需要的时候就会通过代理(A的一个属性)来调用B去完成一些事情,A不需要知道B是如何完成的,他只关心结果,而B也不需要知道A为什么要做这件事,以及A拿到结果之后会干什么,B只需要完成自己的工作返回正确的结果即可。

以上就是我对协议和代理的一些理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值