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

刚开始接触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的关系的更多相关文章

  1. [HMLY]12.iOS中的Protocol

    最近工作中遇到一个比较迷惑的事情,在我利用runtime获取类的属性的时候,由于类实现了一个自定义协议,导致遍历出来的属性中包含了NSObject协议中的property.查来查去,只是知道和prot ...

  2. 对iOS中Delegate的理解

    首先 协议protocol 和委托delegate 是两个完全不同的概念  放在一起说 是因为我们总是在同一个头文件里看到它们: 首先解释一下什么是委托 :举个例子 ,我工作的时候给你打电话,让你帮我 ...

  3. 06 (OC)* iOS中UI类之间的继承关系

    iOS中UI类之间的继承关系 此图可以更好的让你去理解iOS中一些底层的关系.你能够了解以及理解UI类之间的继承关系,你会更加明白苹果有关于底层的东西,更有助于你的项目开发由它们的底层关系,就能更加容 ...

  4. iOS 中 UIView 和 CALayer 的关系

    UIView 有一个名叫 layer ,类型为 CALayer 的对象属性,它们的行为很相似,主要区别在于:CALayer 继承自 NSObject ,不能够响应事件. 这是因为 UIView 除了负 ...

  5. 【转】iOS开发-Protocol协议及委托代理(Delegate)传值

    原文网址:http://www.cnblogs.com/GarveyCalvin/p/4210828.html 前言:因为Object-C是不支持多继承的,所以很多时候都是用Protocol(协议)来 ...

  6. 关于IOS中的delegate必须知道的事情

    当你开始写iOS程式不久,应该开始面对到很多的delegate, 不管是用别人的library或是自己写library,可能都逃不了delegate. 为了怕有些人不知道什么是delegate,在这边 ...

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

    ios中关于delegate(委托)的使用心得 分类: iOS开发2012-05-15 10:54 34793人阅读 评论(9) 收藏 举报 iosuiviewtimerinterfaceprinti ...

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

    前言:因为Object-C是不支持多继承的,所以很多时候都是用Protocol(协议)来代替.Protocol(协议)只能定义公用的一套接口,但不能提供具体的实现方法.也就是说,它只告诉你要做什么,但 ...

  9. iOS中 Proxy和的delegate区别

    在ios中使用proxy代理模式,经常容易和delegate委托模式混淆. 委托模式(delegate),是简单的强大的模式,可让一个对象扮演另外对象的行为.委托对象保持到另外对象的引用,并在适当的时 ...

随机推荐

  1. 重学JAVA基础(七):线程的wait、notify、notifyAll、sleep

    /** * 测试thread的wait notify notifyAll sleep Interrupted * @author tomsnail * @date 2015年4月20日 下午3:20: ...

  2. Eclipse崩溃后无法启动的问题解决

    一次Eclipse发生内存溢出(ADT环境,多打开几个xml文件内存占用就会飚升),强制结束任务,再次启动Eclipse发现闪退.查看workspace/.metadata/.log文件发现如下错误信 ...

  3. 采用TL026等构成的宽带ALC放大器电路图

    Building a Differential Amplifier An op-amp with no feedback is already a differential amplifier, am ...

  4. vector的 emplace 和 insert 以及使用vector进行iterator遍历 且 erase的时候注意事项

    vector<int> first;//Size()==2 first.push_back(); first.push_back(); //first.insert(2); vector& ...

  5. 支付宝Wap支付你了解多少?

    上几篇文章详细介绍了支付宝APP支付.微信APP支付 此文章来介绍下支付宝Wap支付(也叫作手机网站支付) 目录 1.创建应用并获取APPID 2.配置应用环境 3.配置沙箱环境 4.服务端实现(Ma ...

  6. samba4.1.9安装

    ./configure \ --prefix=/usr \ --sysconfdir=/etc \ --localstatedir=/var \ --with-piddir=/run/samba \ ...

  7. C++程序中调用MPI并行的批处理命令

    问题来源:在使用MPI时,将程序并行实现了,运行时需要在dos窗口下输入批处理命令,以完成程序的执行. 如:mpiexec -localroot -n 6 d:/mpi/pro.exe 但每次这样挺麻 ...

  8. Enclosure POJ

    0:Enclosure http://poj.openjudge.cn/challenge3/0/ 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  131072kB 描述 为了防止 ...

  9. Goldengate进程的拆分与合并

    Goldengate的拆分与合并分类: ORACLE GoldenGate 2013-10-10 15:22 721人阅读 评论(0) 收藏 举报在使用Goldengate作为复制解决方案时,随着负载 ...

  10. iis7下iis安全狗不能用怎么办(安装iis6兼容性)

    is7下iis安全狗不能用怎么办 | 浏览:126 | 更新:2015-05-14 17:11 1 2 3 4 5 6 分步阅读 windows系统iis安全狗是常用的一款软件,针对网站使用很方便.在 ...