在IOS中委托通过一种@protocol的方式实现,所以又称为协议.协议是多个类共享的一个方法列表,在协议中所列出的方法没有响应的实现,由其它人来实现.这叫好比我想买个手机,所以我有个buyIphone 方法,但是我不知道谁那买手机,所以把这个需求发布出去(比如公布在网站上),如果有卖手机的商人(也就是说他能实现buyIphone这个方法)看到,他就会接受我的委托,(在商人自己的类中实现<XXXdelegate>),那么我的委托对象就指向了这个商人..当我要买手机的时候,直接找他就行了.
例如:
@protocol MyDelegate
-(void)buyIphone:(NSString *)iphoneType money:(NSString *)money; @end
@interface My : NSObject
{
id<MyDelegate> deleage;
}
@property(assign,nonatomic)id<MyDelegate> delegate;
@end
代码中声明了一个协议 名叫Mydelegate,在其中有一个buyIphone方法,即一个委托项。当我要购买手机的时候只需要通过delegate 调用 BuyIphone方法即可.
如下:
-(void)willbuy
{
[delegate buyIphone:@"iphone 4s" money:@"4888"]; }
我不必关心谁现实了这一委托,只要实现了这个委托的类,并且buyIphone是声明的委托中必须实现的方法,那么就一定能够得到结果.
例如:商人类实现了这一委托(用<Mydelegate>表示实现)
#import <Foundation/Foundation.h>
#import "My.h"
@interface Business : NSObject<MyDelegate> @end
然后在 @implementation Business 中调用 buyIphone方法
#import "Business.h" @implementation Business -(void)buyIphone:(NSString *)iphoneType money:(NSString *)money
{
NSLog(@"手机有货,这个价钱卖你了,发货中!!");
}
@end
4 天前 上传下载附件 (18 KB) 委托方法通常包括3种动词:should、will、did。
should表示一个动作发生前,通常带有返回值,可以在动作发生之前改变对象状态。
will在动作发生前,委托可以对动作做出响应,但不带有返回值。
did在动作发生后做出的响应。
从方法的定义我们不难看出委托模式能够起到两方面的作用:
第一:委托协助对象主体完成某项操作,将需要定制化的操作通过委托对象来自定义实现,达到和子类化对象主体同样的作用。
第二:事件监听,委托对象监听对象主体的某些重要事件,对事件做出具体响应或广播事件交给需要作出响应的对象。
个人理解采用委托模式的好处在于:
1、避免子类化带来的过多的子类以及子类与父类的耦合
2、通过委托传递消息机制实现分层解耦
委托模式的实现思路:
1、通常是在对象主体包含一个委托对象的弱引用:
@interface A : NSObject
{
IBOutlet id delegate;
} -(id) delegate;
-(void) setDelegate:(id)obj;
2、委托对象的实现有两种方式:正式协议和非正式协议,对象主体在协议中定义委托方法,委托对象可以选择实现其中某些委托方法,因此如果通过正式协议定义委托方法需要使用@option。
@protocol NSSearchDelegate
@option
-(void)didSearchFinish:(*NSNotification) aNotification;
@end
3、连接对象主体和委托,无非就是通过setDelegate:(id)obj来实现。
4、触发委托方法。
昨天做了一个demo,用到了简单代理。
delegate是ios编程的一种设计模式。我们可以用这个设计模式来让单继承的objective-c类表现出它父类之外类的特征。昨天这个代理实现如下:
类GifView是继承自UIView的,它加载在RootViewController上来通过一个Timer播放动画。同时,RootViewController需要知道Timer的每次执行。
代码如下。
首先,定义GifView,在其头文件中定义代理EveryFrameDelegate,同时声明方法- (void)DoSomethingEveryFrame;
#import <UIKit/UIKit.h> @protocol EveryFrameDelegate <NSObject> - (void)DoSomethingEveryFrame; @end @interface GifView : UIView
{
NSTimer *timer;
id <EveryFrameDelegate> delegate;
NSInteger currentIndex;
} @property (nonatomic, retain) id <EveryFrameDelegate> delegate; @end
然后,只要在GifView.m中让Timer在每次执行的时候调用delegate来执行DoSomethingEveryFrame,代码如下
- (id)initWithFrame:(CGRect)frame
{ self = [super initWithFrame:frame];
if (self)
{
timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(play) userInfo:nil repeats:YES];
[timer fire];
}
return self;
} -(void)play
{
[delegate DoSomethingEveryFrame]; }
GifView上的工作就完成了。
下面是RootViewController中的代码,RootViewController只要在定义GifView的时候指定其代理为自身,就可以知道Timer的每次执行:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CGRect rect = CGRectMake(0, 0, 200, 200);
GifView *tmp = [[GifView alloc] initWithFrame:rect];
tmp.delegate = self;
[self.view addSubview:tmp];
[tmp release];
} - (void)DoSomethingEveryFrame
{
NSLog(@"I'm the delegate! I'm doing printing!");
}
GifView中Timer每次执行都会打印一行
I'm the delegate! I'm doing printing!
故,RootViewController就知道Timer的每次执行了。
做程序时,经常会碰到这样一种情况:在对象A中有一个对象B,在B中做某个操作时需要调用A对象的某个方法。这时,我们就需要用代理机制,也叫委托机制。
还记得刚接触面向对象的时候,居然在B对象中又alloc了一个A对象,发现执行方法时没有works,那时不理解新alloc的对象和原来的对象A不是一个东东。
今天专门补习了一下哈,在网上找了一些资料,综合了一下,写了这篇菜鸟教程。
委托代理(delegate),顾名思义,把某个对象要做的事情委托给别的对象去做。那么别的对象就是这个对象的代理,代替它来打理要做的事。反映到程序中, 首先要明确一个对象的委托方是哪个对象,委托所做的内容是什么。委托机制在很多语言中都用到的,这只是个通用的思想,网上会有很多关于这方面的介绍。
下面以一个简单的例子介绍一下委托:
一、新建iPhone项目DelegateDemo;
二、添加UIView类ViewA;
三、ViewA.h的内容如下:
- #import <UIKit/UIKit.h>
- @protocol <a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a>; //申明代理协议
- @interface ViewA : UIView {
- id <<a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a>> _viewADelegate;
- }
- @property (nonatomic, assign) id viewADelegate; //定义代理的属性,同时要在.m加中
- @end
- //代理协议的内容
- @protocol <a href="http://www.wuleilei.com/" target="_blank"><span style="color:#ff0000">ViewADelegate</span></a> <NSObject>
- - (void)<span style="color:#008080">viewACallBack</span>;
- @end
- View.m中:
- <span> </span>@synthesize viewADelegate = _viewADelegate;
三、在DelegateDemoViewController.m中:
- (void)viewDidLoad {
ViewA *viewA = [[ViewA alloc] initWithFrame:CGRectMake(50, 100, 200, 100)];
viewA.viewADelegate = self; //设置viewA的代理为当前对象自己
[self.view addSubview:viewA];
[viewA release];
[super viewDidLoad];
} - (void)viewACallBack {
NSLog(@"Hi, I am back!");
}
四、
点击此处下载示例。