转iOS中delegate、protocol的关系

iOS中delegate、protocol的关系

分类: iOS Development2014-02-12 10:47 277人阅读 评论(0) 收藏 举报

delegateiosprocotolcategoryobject-c

刚开始接触iOS,对delegate、protocol这两个概念比较模糊。参考了一些资料,记录下来体会。

1.protocol

protocol和interface的概念类似,是object-c语法的一部分。protocol就是一系列不属于任何类的方法的列表。其中声明的方法能被任何类实现。只在protocol中定义行为,在不同的情况下使用不同的实现。这种模式一般称为代理模式。在iOS和OS X开发中,Apple采用了大量的代理模式来实现MVC中View和Controller的解耦。

如何定义protocol呢?

在声明文件(h文件)中通过关键字@protocol定义,然后给出Protocol的名称,方法列表,然后用@end表示Protocol结束。在@end指令结束之前定义的方法,都属于这个Protocol。

@protocol myProtocol <NSObject>

@required
- (int)add:(int) a and:(int)b;

@optional
- (int)minus:(int)a and:(int)b;

@end

这里还有两个关键字,@required和@optional,一个是必须实现的,一个是可选的。可以根据名字直接判断。

如何使用这个protocol呢?

@interface text : NSObject<myProtocol>

@end

定义一个类来使用protocol,用尖括号(<...>)括起来的就是我们定义的protocol,如果要采用多个Protocol,可以在尖括号内引入多个Protocol名称,并用逗号隔开即可。

在这个类的实现文件中来实现方法:

@implementation text
- (int)add:(int)a and:(int)b{
    return a + b;
}
- (int)minus:(int)a and:(int)b{
    if (a >= b) {
        return a - b;
    }
    else
        return b - a;
}
@end

iOS中Protocol和Java语言中的interface很类似,如果一些类之间没有继承关系,但是又具备某些相同的行为,则可以使用Protocol来描述它们的关系。不同的类,可以遵守同一个Protocol,在不同的场景下注入不同的实例,实现不同的功能。Cocoa框架中大量采用了这种模式实现数据和UI的分离。例如UIView产生的所有事件,都是通过委托的方式交给Controller完成。根据约定,框架中后缀为Delegate的都是Protocol,例如UIApplicationDelegate,UIWebViewDelegate等。

2.delegate

delegate和protocol没什么关系,Delegate本身应该称为一种设计模式。是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。在执行一个类的方法的时候,想在这个方法里面跳到另外一个类执行另外一个类的方法,就可以把delegate设置为另外一个类。

举个例子:如果我在工作的时候想知道某场nba比赛的结果和喜欢的球星的数据,但是我在工作,不可以干与工作无关的事情,我可以选择发消息给两个人,让他们查一下结果告诉我,一个去查比赛结果,一个去查喜欢球星的数据,然后我继续工作。等过了一会,这两个人查到想要的东西,把结果返回给我(通知我)。那么这两个人就是我的不同的委托对象。我.delegate = 某人。

如何使用delegate:用上面描述的例子来开始:

先定义一个 代理类 person1  person.h如下:

#import <UIKit/UIKit.h>

@protocol queryDelegate <NSObject>
- (NSString *)query;
@end

@interface Person1 : UIViewController<queryDelegate>
@end

person.m

- (NSString *)query{
    NSString * result = [NSString stringWithFormat:@"热火赢太阳:103比98"];
    return result;

}

首先定义了协议与方法,代理类person1遵循这个协议,并且实现了委托方法。

同样定义一个代理类person2,person2.h

#import <UIKit/UIKit.h>
#import "Person1.h"

@interface Person2 : UIViewController<queryDelegate>

@end

person2.m

- (NSString *)query{
    NSString * data =[NSString stringWithFormat:@"詹姆斯的数据是37分9篮板3助攻" ];
    return data;
}

代理类person2同样遵循某个协议,并且实现了委托方法。

我们在界面上添加两个button和 label,要求点击上面的button,会在它下面的label上显示今天nba  热火vs太阳的比赛结果。点击下面的button的时候,会在下面的lable显示今天比赛的詹姆斯的数据;

添加完界面,给两个button 设置action 给两个label设置 outlet,ok,设置好之后,界面如下:

delegateViewController.h:

#import <UIKit/UIKit.h>
#import "Person1.h"
#import "Person2.h"
@interface delegateViewController : UIViewController

@property (weak,nonatomic) id<queryDelegate> delegate;//声明delegate

- (IBAction)button1Action:(id)sender;
- (IBAction)button2Action:(id)sender;
@property (weak, nonatomic) IBOutlet UILabel *labelResult;
@property (weak, nonatomic) IBOutlet UILabel *labelData;

@end

下面看delegateViewController.m:

#import "delegateViewController.h"

@interface delegateViewController ()

@end

@implementation delegateViewController

@synthesize labelData;
@synthesize labelResult;

.....
- (IBAction)button1Action:(id)sender {

    Person1 *pe1 = [[Person1 alloc] init];
    self.delegate = pe1;//设置代理对象为person1
    NSString * result = [self.delegate query];//通过委托变量调用委托方法
    [labelResult setText:result];
}

- (IBAction)button2Action:(id)sender {
    Person2 *pe2 = [[Person2 alloc]init];
    self.delegate = pe2;//设置代理对象为person2
    NSString* data = [self.delegate query] //通过委托变量调用委托方法
    [labelData setText:data];

}

这一步主要做的是声明委托变量,设置代理,并且通过委托变量调用委托的方法。

执行结果:

delegate概念的作用:

先看书上给出的经典说法:

1.The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.

委托的主要价值是让你可以在一个核心对象里定制多个对象的功能特性。

2.构建helper object 的工具 Helper Object are commonly used to add functionality to an existing class without having to subclass it.

构建helper object,helper object用来对已有的类添加功能特性而不是通过子类继承实现。

下面转载一篇个人认为对delegate比较经典的解释,原文地址:点击打开链接

Delegate本身应该称为一种设计模式。是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。
比如ClassC

@interface ClassC {
    id delegate;
}
@end

首先定义一个id类型的变量,名字叫做delegate。那么ClassC的实现(.m文件)里就可以用delegate这个变量了。当然这里完全可以用其它名字而不是delegate。

我们也可以这样写:

@interface ClassC {
    ClassB *delegate;
}
@end

这样我们知道了delegate是一个ClassB,它就可以提供ClassB里的方法。可以把一部分ClassC里的工作放在ClassB里去实现。这样的写法看起来是不是有点奇怪?或者应该写成这样?

@interface ClassC {
    ClassB *classB;
}
@end

.......按照上面这样写,delegate就没有了。

所以说其实delegate只是一种模式,大家约定俗成,当把自己内部一部分实现暴露给另外一个类去做的时候,就叫实际做事的类为delegate。

为什么会需要把内部实现提出来给另一个类做呢?最常见的目的就是为了在隐藏实现的前提下,提供一个自定义的机会。比如Apple提供的iOS SDK里就有众多的delegate,比如最常用的UITableView,我们没法知道Apple怎么重用UITableViewCell,怎么处理UITableView里Cell的增加、删减,因为我们没有源码。但是我们可以通过实现Delegate的方法来控制一个UITableView的一些行为。UITableViewDataSource其实和delegate是一样一样的,只是由于意义不同换了个名字罢了。

protocol在此扮演了什么角色呢?
        protocol是一种语法,它提供了一个很方便的、实现delegate模式的机会。
        比如写UITableView的时候,Apple这么干

UITableView.m:

- (void)doSomething {
[self blahblah];

[self.delegate guruguru];//放到delegate中去执行这个guruguru函数

[self blahblah];
}

delegate是我们写的类,这个类如果可以被传给UITableView做为其delegate,那唯一要求,就是它实现了

- (void)guruguru;

这个方法。

如果我们把这个方法定义在一个protocol里

@protocol XXXProtocol

- (void)guruguru;

@end

就说明了,UITableView需要的delegate是一个conform to XXXProtocol的类。这就正好是id<XXXProtocol>表达的意思。

无论具体的类是什么,它还有其它什么方法,只要它conform to这个protocol,就说明它可以被传给UITableView,作为它的delegate。那么Apple为了让我们知道这个protocol是delegate需要conform的protocol,它就把XXXProtocol改成了UITableViewDelegate。

这样我们看到protocol的名字里有Delegate,就知道这个protocol里的函数是用来做自定义(Customization)的了。

delegate是对别的对象指针,按MVC一般最好赋值对象是Controller,它实现的是一种模式,它本身不是模式。Protocal是一组方法的定义。当id<protocal>定义为delegate时,就是要用别的对象即赋值的delegate去实现protocal里的方法,这个过程使用的模式就是代理模式。Delegate类+protocal的话就保证了你另外实现的delegate类里面必须有这个委托方法,但至于delegate类还可以干其他事情。

转iOS中delegate、protocol的关系,布布扣,bubuko.com

时间: 2024-10-06 20:19:52

转iOS中delegate、protocol的关系的相关文章

iOS 中delegate的理解与使用(传值)

之前做了半年的iOS,刚入了门,又被拉去转战java,现在iOS的那位大佬离职了,又被弄过来维护app,之前对于iOS中的delegate一直都是半知半解,所以刚好趁着这个机会把我所了解的记下来,以便日后查阅. - delegate的理解 delegate, 也就是代理模式(设计模式的一种),我现在所了解的代理模式是,当我有事要做但是没空的时候,我就可以请别人帮下忙,我告诉你我要做什么,但是具体怎么做,那是你的事了,就比如说,我想去约个妹纸出来玩,但是自己刚好现在有事不能约,或者自己不好意思约,

【转载】iOS中delegate,notification,KVO三种模式实现通信的优缺点

原帖地址:http://blog.csdn.net/yangxt/article/details/8176636 在开发iOS中,有三种模式来实现controller之间的通信: 1.委托delegation: 2.通知中心Notification Center: 3.键值观察key value observing,KVO 因此,那为什么我们需要这些模式以及什么时候用它以及什么时候不用它. 1.delegate 基本特征: 一 个controller定义了一个协议(即一系列的方法定义).该协议描

[HMLY]12.iOS中的Protocol

最近工作中遇到一个比较迷惑的事情,在我利用runtime获取类的属性的时候,由于类实现了一个自定义协议,导致遍历出来的属性中包含了NSObject协议中的property.查来查去,只是知道和protocol有关.晚上问了下朋友(iOS大神),结果被他一句点破.发现这部分知识点遗漏了一点. protocol类似java中的interface,主要是用来定义一套对象之间的通信规则.protocol也是我们设计时常用的一个东西,相对于直接继承的方式,protocol则偏向于组合模式.因为在设计对象的

iOS中delegate代理对象使用weak和assign哪个?

在定义delegate对象的时候,我们经常看到可以使用weak 和 assign 但是到底哪个使用更合适呢? 首先:使用assign,声明的对象即使对象销毁了,但是指针依然存在,这样造成声明的对象变成了野指针,这样导致内存泄露. 而使用 weak ,当对象销毁时,即将delegate = nil,这样不会产生野指针这种情况出现. 所以答案很明显 我们在定义代理对象的时候,通常使用weak来修饰.

编程比喻之protocol和delegate之间的关系

编程比喻之protocol和delegate之间的关系 开篇: 当你还在忍受传统老套的讲解,被专业术语搞的晕头转向时,编程比喻横空出世,且打个酱油再回. 卖萌结束, 主角 protocol/delegate之间的爱恨情仇. 小故事 寿寿最近心血来潮,注册了一家公司iceAna,打算搞ios开发,心想:反正现在的公司没业务,一台电脑一个人足以.就这样,代码寿寿写,设计寿寿搞,连拖地烧饭都得自己干! 重要寿寿开发的一款软件得到了上市公司的赏识,立马给了500万投资.寿寿心想,公司要做到看来靠一个人的

iOS 中 UIView 和 CALayer 的关系

UIView 有一个名叫 layer ,类型为 CALayer 的对象属性,它们的行为很相似,主要区别在于:CALayer 继承自 NSObject ,不能够响应事件. 这是因为 UIView 除了负责响应事件 ( 继承自 UIReponder ) 外,它还是一个对 CALayer 的底层封装.可以说,它们的相似行为都依赖于 CALayer 的实现,UIView 只不过是封装了它的高级接口而已. 那 CALayer 是什么呢? CALayer(图层) 文档对它定义是:管理基于图像内容的对象,允许

iOS 中KVC、KVO、NSNotification、delegate 总结及区别

iOS 中KVC.KVO.NSNotification.delegate 总结及区别 1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的关键技术之一. Demo: @interface myPerson : NSObject { NSString*_name; int      _age; int      _height; int      _w

iOS开发-Protocol协议及委托代理(Delegate)传值

前言:因为Object-C是不支持多继承的,所以很多时候都是用Protocol(协议)来代替.Protocol(协议)只能定义公用的一套接口,但不能提供具体的实现方法.也就是说,它只告诉你要做什么,但具体怎么做,它不关心. 当 一个类要使用某一个Protocol(协议)时,都必须要遵守协议.比如有些必要实现的方法,你没有去实现,那么编译器就会报警告,来提醒你没有遵守×× 协议.注意,我这里说的是警告,而不是错误.对的,就算你不实现那些“必要实现”的方法,程序也是能运行的,只不过多了些警告. 我会

ios中关于delegate(委托)的使用心得

从开始从事OC工作到现在大概1年多了,从当初接触oc的"协议"的不明白,到现在代码中随处可见的委托,协议,其中感悟颇多. 首先,大家应该都明白的是委托是协议的一种,顾名思义,就是委托他人帮自己去做什么事.也就是当自己做什么事情不方便的时候,就可以建立一个委托,这样就可以委托他人帮自己去实现什么方法. 其次,我简单的总结了一下自己用到的委托的作用有两个,一个是传值,一个是传事件. 1.所谓传值经常用在b类要把自己的一个数据或者对象传给a类,让a类去展示或者处理.(切分紧耦合,和代码分块的