现在的位置: 首页 > 综合 > 正文

IOS 中delegate 讲解1_legend

2014年09月05日 ⁄ 综合 ⁄ 共 5228字 ⁄ 字号 评论关闭

一::

delegate  的过程::

(1)创建一个代理。

即: 通过协议@protocol来创建一个代理  ADelegate ,其中包含代理函数的声明;

(2)委托者 A 声明一个delegate。

即: 委托者 创建一个类A。该类中有一个实现了该委托协议的属性baseDelegate。

(3)委托者 A 类中 调用delegate内的方法.

即: 委托者类中的函数通过  [this.baseDelegate  函数]  来调用代理内的方法。

(4)在一个 被委托者 类 B 中 , 委托者对象 A1 设置delegate

即: 将一个被委托者的对象  this  赋值给    一个 委托者的对象 A1 的baseDelegate属性

    委托者对象A1.baseDelegate=self;

(5)  被委托者类 B 中 实现Delegate 所定义的方法:

即:  被委托者类 B 通过  继承代理协议  ADelegate 来实现委托中的代理函数。
(相当于重写父类中的函数)

二::delegate 简单理解。

最近刚接触协议@protocol 和委托 delegate 弄得一头雾水  通过这几天的学习有了一定的了解   :

首先 协议protocol 和委托delegate 是两个完全不同的概念  放在一起说 是因为我们总是在同一个头文件里看到它们;

首先解释一下什么是委托 :举个例子 ,我工作的时候给你打电话,让你帮我查某人的电话号码,把事情交给你后,我继续工作 过了几分钟 你打电话回来告诉我 查到的结果。。。@end    
那么你就是我的委托对象,当你完成事件后 返回给我一个值;这就是委托。也就是   :我.delegete = 你;

Delegate本身应该称为一种设计模式。

是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。

比如

设定一个协议方法:delegateMethod 

1 @protocol
MyDelegate 
2    
3 -(void)delegateMethod; 
4    
5 @end

在A类中实现该协议并实现方法:

1 @interface 
A : UIViewController <MyDelegate> 
2    
3 @implementation
4 -(void)delegateMethod 
5
6      NSLog(@"delegateMethod"); 
7 }

在B中定义delegate指针;

1 @interface 
B : UIViewController 
2  
3      id
delegate; 
4  
5  @property(nonatomic,retain)
id delegate; 
6 @end 
7     
8  @implementation
B  
9  @synthesize
delegate;


A到B的过程中给delegate指名代理

1 B.delegate
= self;

B中调用代理方法;

1 [delegate
delegateMethod];

这就是B去委托A实现delegateMethod方法;

其实delegate只是一种模式,大家约定俗成,当把自己内部一部分实现暴露给另外一个类去做的时候,就叫实际做事的类为delegate,当然你也可你把它命名为任何名字; 

三:: 范例::

这是一个计算器App,支持函数的图形展示。 点击右上角的按钮,可弹出函数 列表。 这个列表是一个TableView;  函数图形的展示是另一个视图,我们称之为 GraphicView。  这个实例所展示的是: 当在Tableview选择不同的函数时,函数的绘制图形会随之改变。这里要解决的关键问题是, 如何将所选择的函数告知 函数图形视图? 

先说明下,这是基于Storyboard 创建的工程。 工程本身有些复杂,我们不再从头讲起,这里着重讲解 @protocol 的使用。

 通常,一个delegate的使用过程,需要经过五步:

1.     创建一个 delegate;

2.    委托者声明一个delegate;

3.    委托者调用delegate内的方法(method);

4.    被委托者设置delegate,以便被委托者调用;

5.    被委托者实现Delegate 所定义的方法。

 

接下来,我们来一步一步实现:

1.1    第一步: 创建一个delegate
在 .h 文件中,  通过 @protocol 创建一个 delegate:

@protocol CalculatorProgramsTableViewControllerDelegate

 

@optional

- (void)calculatorProgramsTableViewController:

    (CalculatorPorgramTableViewController *)sender

                                 choseProgram:(id)program;

@end

 

代码解释:

@protocol CalculatorProgramsTableViewControllerDelegate

用来创建一个delegate。  这个delegate 中有一个方法:

 

(void)calculatorProgramsTableViewController

@optional 表明,这个方法是不要求一定实现,是可选的。

 

小贴士:

这里需明确一个概念, 虽然通过@protocol 定义了一个delegate,但不能说, delegate 就是protocol。  前面提到过,delegate是一种架构设计模式。 在iOS中,它是通过@protocol 来实现的。

1.2    第二步: 委托者声明一个delegate
 

在TableView 的 .h 文件中 (CalculatorProgramsTableViewController.h), 将之前创建的delegate 通过@property 进行声明。 代码如下:

@interface CalculatorProgramsTableViewController : UITableViewController

...

// Define a property delegate

@property (nonatomic, weak) id<CalculatorProgramsTableViewControlerDelegate>

                            delegate;

...

@end

添加这几行代码后 , TableView 便拥有了Delegate。 有了Delegate, TableView就可以发消息了。 仅仅是可以发消息了,但还没有发。 下一步,Tableview 开始发送消息。

 

 1.3    第三步:委托者调用delegate内的方法

我们的目标是:  当在TableView 上选择不同的函数时, TableView 将这个所选定的函数,告知绘制函数图形的GraphicView。

这一步,TableView  通过调用delegate的方法,发送消息。代码实现如下:

 

#progma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView

    didSeelectRowAtIndexPath:(NSIndexPath *)indexPath

{

  id program = [self.programs objectAtIndex:indexPath.row];

  [self.delegate calculatorProgramsTableViewController:self

                                          choseProgram:porgram];

}

 

代码解释:

注意到 高亮部分的 self.delegate 了吧。 UITableView 就是通过这个之前定义的delegate 发送消息的。具体做法是: UITableViewController 调用delegate 中所定义的函数。通过这个函数的调用,  实现了消息的发送。但发到哪里去了,还不得而知。这是因为, self.delegate 还没赋值呢。  

接下来,要做的是: 将  self.delegate  设置为GraphicView。

 

1.4     被委托者设置delegate,以便被委托者调用;
 

前面谈到, UITableViewController 中的self.delegate 还没有赋值。既然TableView 想把值传给Graphicview,  那就应该在calculatorGraphViewController.m 文件中设置delegate。 也就是说,让Graphicview 成为Tableview的delegate。

 代码如下:

 

@implementation CalculatorGraphViewController

...

- (void)prepareForSegue:(UIStoryboardSegue *)segue

                 sender:(id)sender

{

  if ([segue.identifier isEqualToString:@"Show Favorite Graphics"]) {

    NSArray * programs = [[NSUserDefaults standardUserDefaults]

                         objectForKey:FAVORITES_KEY];

    [segue.destinationViewController setPrograms:programs];

[segue.destinationViewController setDelegate:self];

// set delegate

  }

}

 

代码解释:

但点击Graphicview 右上角的button 时, 会弹出一个Tableview。同时,在这段代码的最后一行,将CalculatorGraphViewController 设置为Tableview 的delegate。

通过这个设置, Tableview便可以调用Graphicview 所遵循的delegate 的的方法。

Delegate 的这个方法还没实现呢,  赶紧实现它吧。

1.5    被委托者实现Delegate 所定义的方法。
 

还记得那个神秘的 <> 吧。 通过以下代码,让GraphicViewController 来遵循这个delegate。  

// .h to implement the protocol

@interface CalculatorGraphViewController :NSObject

     <CalculatorProgramsTableViewControllerDelegate>

...

@end

 

这是delegate使用的最后一步了, 我们在segue的controller 文件中,实现这个protocol所定义的方法。代码如下:

// implement delegate method

- (void)calculatorProgramsTableViewController:(CalculatorProgramsTableViewController *)sender

                                chooseProgram:(id)program

{

  self.calculatorProgram = program;

}

四   :: delegate  的作用

1). 自己的一部分工作让其他人来做。

自己这个类中有一个 delegate 属性, 通过delegate 属性来调用   其他人实现的代理的函数。

然后这个其他人是谁??

就是  自己这个对象的delegate=谁,谁就是其他人,这个其他人类就需要  实现 代理函数。

自然而然的: 通过自己类中 delegate 属性 就可以

调用代理函数,让其他人来完成 这个工作。

2) . 自己将值  value结构体  传给  其他人 。

就是代理中 有value 结构体 类型 的 成员变量或者属性,以及一些代理函数。

然后自己就是通过delegate 属性 ,调用代理函数来传递这些  value 值给其他人。

例如: A 类将 value 传给 B 类::

1. 设置一个BFatherDelegate 的代理。

其中包含 value 成员变量或属性,以及一些代理函数的声明;

2. B类遵守BFatherDelegate协议,然后在B类中定义这些代理函数。

3. A类中包含一个遵守BFatherDelegate协议的成员变量或者属性

4. 利用A类中的这个属性来调用代理函数,来实现value的传递。

(此时利用A类中 的这个属性,调用代理函数,为什么就可以把值传给B类呢??继续)

5. 在B类中如果想获得A类中的value , 就在B类中创建一个A类的对象,然后将B类对象或者self ,赋值给这个A类对象中的这个代理成员变量。

(请与C++中多态进行比较)

3). 自己发生了某一个事件,对这个事件的响应、处理 让其他人来做。 

参见 http://blog.csdn.net/huifeidexin_1/article/details/7567731

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

抱歉!评论已关闭.