一::
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 |
2 |
|
3 |
-( void )delegateMethod; |
4 |
|
5 |
@end |
在A类中实现该协议并实现方法:
1 |
@interface |
2 |
|
3 |
@implementation |
4 |
-( void )delegateMethod |
5 |
{ |
6 |
NSLog(@ "delegateMethod" ); |
7 |
} |
在B中定义delegate指针;
1 |
@interface |
2 |
{ |
3 |
id |
4 |
} |
5 |
@property(nonatomic,retain) |
6 |
@end |
7 |
|
8 |
@implementation |
9 |
@synthesize |
A到B的过程中给delegate指名代理
1 |
B.delegate |
B中调用代理方法;
1 |
[delegate |
这就是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