您的位置:首页 > 移动开发 > IOS开发

iOS 层层推进实现代理模式

2014-03-27 18:42 357 查看
1.代理模式核心思想:A类委托B类做某件事,然后A类获取B类的执行的返回结果!

举例:女孩想去买电影票,但是自己不亲自去而是委托男孩了解电影电影票信息,同时女孩获得男孩买票的结果,代码模拟实现:

/*********************************** Gril.h *************************************/
#import <Foundation/Foundation.h>
@class Boy;
@interface Gril : NSObject

// “女孩”想去买电影票
- (void)buyTicket;

// “女孩”声明自己的代理对象
@property (nonatomic,retain) Boy *boy;
// @property (nonatomic,retain) Boy *delegate;

@end


/*********************************** Gril.m *************************************/
#import "Gril.h"
#import "Boy.h"

@implementation Gril

// “女孩”想买电影票
- (void)buyTicket
{
// “女孩”直接获取自己的代理(“男孩”)的方法返回值 剩余电影票的个数
int count = [_boy leftTicketsCount];
// “女孩”直接获取自己的代理(“男孩”)的方法返回值 单张电影票的价格
double price = [_boy ticketPrice];

// 输出女孩获得的信息
NSLog(@"还剩%d张电影票,每张票价是%.2f元",count,price);

}

// Girl类引用了Boy类 那么在Girl类释放之前先释放Boy对象
- (void)dealloc
{
[_boy release];
[super dealloc];
}
@end


/*********************************** Boy.h *************************************/
#import <Foundation/Foundation.h>

@interface Boy : NSObject

// 查询单张票价
- (double)ticketPrice;
// 查询还剩多少张电影票
- (int)leftTicketsCount;

@end


/*********************************** Boy.m *************************************/
#import "Boy.h"
@implementation Boy

// 实现单张票价的查询
- (double)ticketPrice
{
return 20;
}

// 实现剩余的电影票
- (int)leftTicketsCount
{
return 3;
}
@end


/*********************************** main.m *************************************/
#import <Foundation/Foundation.h>
#import "Boy.h"
#import "Gril.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Gril *gril = [[[Gril alloc] init] autorelease];
Boy *boy = [[[Boy alloc] init] autorelease];

// 为girl中的boy属性赋值 完成"代理思想"
gril.boy = boy; // gril.delegate = boy;

[gril buyTicket];

}
return 0;
}


小结:[b]可以看出Gril类的代理对象已固定是Boy类,这样的话代码耦合性太强,如果下次需要修改Gril类的代理对象为其他对象则不便于修改[/b]

修改后的代码如下:

/*********************************** Gril.h *************************************/
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"
@class Boy;

@interface Gril : NSObject

// “女孩”想去买电影票
- (void)buyTicket;

// “女孩”声明自己的代理对象为任意对象 但是对象必须遵守TicketDelegate协议
@property (nonatomic,retain) id<TicketDelegate> delegate; //  这样的话 任何对象都可以作为代理对象 只要遵守协议即可

@end


/*********************************** Gril.m *************************************/
#import "Gril.h"
#import "Boy.h"

@implementation Gril

// “女孩”想买电影票
- (void)buyTicket
{
// “女孩”直接获取自己的代理(“男孩”)的方法返回值 剩余电影票的个数
int count = [_delegate leftTicketsCount];
// “女孩”直接获取自己的代理(“男孩”)的方法返回值 单张电影票的价格
double price = [_delegate ticketPrice];

// 输出女孩获得的信息
NSLog(@"还剩%d张电影票,每张票价是%.2f元",count,price);

}

// Girl类引用了Boy类 那么在Girl类释放之前先释放Boy对象
- (void)dealloc
{
[_delegate release];
[super dealloc];
}
@end


// 定义协议
/***************************** TicketDelegate.h文件 ******************************/
#import <Foundation/Foundation.h>

// 定义协议:那么代理对象必须要遵循协议

@protocol TicketDelegate <NSObject>
// 查询单张票价
- (double)ticketPrice;
// 查询还剩多少张电影票
- (int)leftTicketsCount;
@end


/*********************************** Boy.h *************************************/
#import <Foundation/Foundation.h>
#import "TicketDelegate.h"

// 声明代理对象要遵守的协议
@protocol TicketDelegate;

// Boy作为Gril的代理则必须遵守协议
@interface Boy : NSObject <TicketDelegate>

@end


/*********************************** Boy.m *************************************/
#import "Boy.h"
@implementation Boy

// 实现单张票价的查询
- (double)ticketPrice
{
return 20;
}

// 实现剩余的电影票
- (int)leftTicketsCount
{
return 3;
}
@end


/*********************************** main.m *************************************/
#import <Foundation/Foundation.h>
#import "Boy.h"
#import "Gril.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Gril *gril = [[[Gril alloc] init] autorelease];
Boy *boy = [[[Boy alloc] init] autorelease];

// 为girl中的boy属性赋值 完成“代理思想”
gril.delegate = boy; // gril.delegate = boy;

[gril buyTicket];
}
return 0;
}


小结:修改后的代码耦合性相对来比较弱!假设如果再要为Gril类添加代理对象,Gril类本身不需要任何修改,只要新建的代理对象遵守协议即可

2.联想UITableView要显示内容时它本身并不知道要显示要分几组、每组显示多少行、每行显示的内容等,也是要依靠它的代理对象UITableViewDataSource来执行返回的结果会赋值给UITableView中的相应参数,才会进行显示
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: