分类: 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. Comet技术详解:基于HTTP长连接的Web端实时通信技术

    前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...

  2. 阅读开发高手的代码 分享二则.NET开发框架的技巧

    最近阅读了一套ERP开发框架的源代码,对开发框架的理解又深入一层,也为其将知识点运用的如此灵活而自叹不如. 郎咸平教授说,国际金融炒家对国际金融知识的理解与运用程序,是不可想像的.1997年的亚洲金融 ...

  3. .NET中的流

    当应用程序需要和磁盘上的文件打交道的时候,就有了流的概念.流就像架设在应用程序所在内存和磁盘之间的一个管道. 大致思路 → 建立管道 //FileMode.Open打开现有文件,另外还有FileMod ...

  4. “代理XP”组件已作为此服务器安全配置的一部分被关闭的解决办法

    代理XP”组件已作为此服务器安全配置的一部分被关闭.系统管理员可以使用sp_configure来启用“代理XP”.有关启用“代理XP”的详细信息,请参阅SQL Server联机丛书中的“外围应用配置器 ...

  5. eclipse android logcat 只显示自己应用程序信息的设置方法

    1 elcipse 中往往会在logcat中显示 all message ,而这里面的信息太多,根本没有办法进行区分.如图: 2 我们想显示自己项目的 logcat .下面开始设置. 3 首先点击上面 ...

  6. mac上使用生成RSA公钥和密钥

    关于RSA加密解密的问题,没事弄了一下,先把主要的流程保存下来,以备交流或者以后用. 首先确保你的电脑上安装了openssl,一般mac系统安装后都会自动安装!怎么安装??.....请百度...... ...

  7. BW基于ALE的主数据增量机制分析

    1     概述 前段时间在项目中碰到一个问题,地点物料0MAT_PLANT_ATTR属性主数据因为有两个多月没有做增量更新,导致在之后的每次增量抽取活动中因为抽取的数据量过大使得在源系统的进程中发生 ...

  8. RabbitMQ学习笔记3-使用topic交换器

    topic的路由规则里使用[.]号分隔单词,使用[*]号匹配1个单词,使用[#]匹配多个.和多个*. 在下面的例子中: logger.*可以匹配logger.error和logger.warning, ...

  9. (转)新手必看:HighCharts几个基础问答

    转自:http://bbs.hcharts.cn/article-21-1.html

  10. sql2008清空日志

    USE[master] GO ALTER DATABASE MeSizeSNS SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE MeSizeSNS ...