分类: 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. A new start

    学习前端已经有一年多,也自己写过不少博客.笔记,但是比较不开心的是有时候自己写的博客自己都看不懂,所以最后决定重新开一个博客,目标是写能让别人看懂也能让自己看懂的东西,那才算真成功真的懂了.最后希望的 ...

  2. Goodchild教授关于GIS的四大预测的不同看法

    Goodchild教授的关于GIS的4个未来发展的预测不断有人在微信朋友圈里转发,虽然现在做的工作GIS只是一个基本的工具之一了,但对这4个预测还是有不少不同看法和一点自己的意见. Goodchild ...

  3. 【转】javascript运行机制之this详解

    this是面向对象语言中一个重要的关键字,理解并掌握该关键字的使用对于我们代码的健壮性及优美性至关重要.而javascript的this又有区别于Java.C#等纯面向对象的语言,这使得this更加扑 ...

  4. windows & mac 安装lua

    mac从源码编译安装是最方便的,lua源码不足两万行,编译几秒钟的事. 打开terminal,依次输入以下命令: curl -R -O http://www.lua.org/ftp/lua-5.2.3 ...

  5. Android UI系列-----EditText和AutoCompleteTextView

    在这篇随笔里将主要讲解一下EditText和AutoCompleteTextView这个控件 1.EditText 首先我们先简单来说说EditText这个控件,这个就相当于我们平常web开发中的文本 ...

  6. MySQL 错误

    (1) Ignoring query to other database D:\Program Files\MySQL\MySQL Server 5.6\bin>mysql -Uroot 原因是 ...

  7. IOS 7 UI 的适配

    官方问题答案:https://developer.apple.com/library/ios/qa/qa1797/_index.html 官方建议: https://developer.apple.c ...

  8. 【C++沉思录】句柄2

    1.[C++沉思录]句柄1 存在问题: 句柄为了绑定到Point的对象上,必须定义一个辅助类UPoint,如果要求句柄绑定到Point的子类上,那就存在问题了.2.有没有更简单的办法呢? 句柄使用Po ...

  9. Activemq消息持久化

    官方文档: http://activemq.apache.org/persistence.html ActiveMq持久化相关配置:/usr/local/apache-activemq-5.11.1/ ...

  10. Scala 深入浅出实战经典 第64讲:Scala中隐式对象代码实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...