使用委托的步骤
1. 创建一个协议
2. 添加一个委托属性
到委托者
(普通对象)的公共interface
3. 在委托者
的实现中使用此委托属性
4. 在委托
(委托对象)的实现的某个地方设置此委托代理
属性
5. 在委托
中实现协议方法(include <> on @interface)
步骤1、2、3可在委托者里实现,步骤4、5在委托中实现(通常是某个ViewController原因作为委托)
这里涉及到两个对象(委托者、委托),一个是普通对象,一个是委托对象。希望你没有被它们的名字搞混。普通对象负责定义一个协议和一个属性,委托对象负责响应普通对象的委托,因此委托对象要实现此协议,且在其自身实现的某个地方设置此委托属性指向为自己。
上面的说明可能仍然让你觉得不清楚,让我们来看看代码吧。下面这些代码是斯坦福大学的iOS 5公开课里的demo的片段,上面的5个步骤也来自其中,其原文为:
- Create the
@protocol
- Add
delegate @property
todelegator
’s public @interface - Use
delegate property
insidedelegator
’s implementation - Set the
delegate property
somewhere inside thedelefate
’s @implementation - Implement the protocol’s mothod(s) in the
delegate
(include <> on @interface)
其使用委托的目的是:由HappinessViewController提供数据,让FaceView使用此数据更新自己view的绘制,画出不同的人脸形状。因为FaceView有一个IBOutlet在HappinessViewController中,所以看起来比较奇怪步骤4很容易就可以实现。注意下面代码的注释。
普通对象
-
FaceView.h
#import <UIKit/UIKit.h> @class FaceView; // step 1: 定义协议,我们取其名为DataSource,就是要从委托对象那里获取数据 @protocol FaceViewDataSource - (float)smileForFaceView:(FaceView *)sender; @end @interface FaceView : UIView @property (nonatomic) CGFloat scale; - (void)pinch:(UIPinchGestureRecognizer *)gesture; // step 2: 定义一个委托属性 @property (nonatomic, weak) id <FaceViewDataSource> dataSource; @end
-
FaceView.m
.... // 在drawRect方法中, // step 3: 使用委托数据源的方法为本地属性赋值 float smile = [self.dataSource smileForFaceView:self]; // 所以上面这句在整个步骤都完成时,可以这么理解,给ViewController发送消息smileForFaceView:self,利用其返回值设置自己的smile属性 ....
委托对象
-
HappinessViewController.m
定义要实现此协议(私有),且这个ViewController有个私有的FaceView输出口
#import "HappinessViewController.h" #import "FaceView.h" @interface HappinessViewController () <FaceViewDataSource> @property (weak, nonatomic) IBOutlet FaceView *faceview; @end
再在实现里,设置此FaceView的dataSource为自己(ViewController),并实现协议规定的方法
@implementation HappinessViewController
@synthesize happiness = _happiness;
@synthesize faceview = _faceview;
- (void)setHappiness:(int)happiness
{
_happiness = happiness;
[self.faceview setNeedsDisplay];
}
- (void)setFaceview:(FaceView *)faceview
{
_faceview = faceview;
[self.faceview addGestureRecognizer:[[UIPinchGestureRecognizer alloc] initWithTarget:self.faceview action:@selector(pinch:)]];
[self.faceview addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleHappinessGesture:)]];
// step 4: 设置此FaceView的dataSource为自己
self.faceview.dataSource = self;
}
// step 5: 实现协议规定的方法
- (float)smileForFaceView:(FaceView *)sender
{
return (self.happiness - 50) / 50.0;
}
....
刚开始遇到要使用委托的情况,可能会有些迷惑,但多使用几次,熟悉之后就好了。关键就是普通对象需要委托对象做些什么
?为此,它们双方都要用代码做些准备工作。