A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wdcew 中级黑马   /  2015-8-15 23:50  /  1722 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 wdcew 于 2015-8-15 23:53 编辑

代理(delegate)模式
委托(delegate)也叫代理是iOS开发中常用的设计模式。我们借助于protocol(参考博文:objective-c协议(protocol))可以很方便的实现这种设计模式。
什么是代理?
苹果的官方文档给了很清晰的解释:
Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.
意译一下就是:代理是一种简单而功能强大的设计模式,这种模式用于一个对象“代表”另外一个对象和程序中其他的对象进行交互。 主对象(这里指的是delegating object)中维护一个代理(delegate)的引用并且在合适的时候向这个代理发送消息。这个消息通知“代理”主对象即将处理或是已经处理完了某一个事件。这个代理可以通过更新自己或是其它对象的UI界面或是其它状态来响应主对象所发送过来的这个事件的消息。或是在某些情况下能返回一个值来影响其它即将发生的事件该如何来处理。代理的主要价值是它可以让你容易的定制各种对象的行为。注意这里的代理是个名词,它本身是一个对象,这个对象是专门代表被代理对象来和程序中其他对象打交道的。

代理设计模式的场合:
* 当对象A发生了一些行为,想告知对象B (让对象B成为对象A的代理对象)
* 对象B想监听对象A的一些行为 (让对象B成为对象A的代理对象)
  • 当对象A无法处理某些行为的时候,想让对象B帮忙处理 (让对象B成为对象A的代理对象)

delegate的设置与委托
//一直以来,委托的类型一直使用id类型。
    id <baomuDelegate> delegate;
//委托也可以作为属性申明,一般使用assign!!
//@property(nonatomic, assign)id<baomuDelegate> Delegate;
//在ARC下,使用@property(weak)id<baomuDelegate> Delegate;
  • 设置委托、返回对象的方法类型:
- (void) setDelegate:(id<baomuDelegate>) newBaomu;
  • (id <baomuDelegate>)delegate;

需要记住的关键是在发出代理请求的类(A)中声明代理人(B)的实例变量,这样就可以保证A 能通过调用B中B代理的方法来完成B代理的事情,即自己代理给B 的事情。

下面来举一个经典的实例,妈妈和保姆的例子:妈妈把孩子委托给保姆照顾,于是将需要完成的事情写成一个协议:
协议声明如下:
@protocol baomuDelegate<NSObject>
@required
- (void)takeEat;
- (void)takeSleep;
- (void)takeShower;
- (void)takePlay;
@end

@interface baomu : NSObject<baomuDelegate>

@end


代理人Baomu类
@interface baomu : NSObject<baomuDelegate>

@end


实现文件:
@implementation baomu

- (void)takeSleep
{
    NSLog(@"小孩困了,让他睡觉");
}
- (void)takeShower
{
    NSLog(@"小孩脏了,帮他洗澡");
}
- (void)takePlay
{
    NSLog(@"跟小孩一起玩");
}

-(void) dealloc
{
    NSLog(@"baomu is dealloc");
}
@end

声明一个morther类
#import <Foundation/Foundation.h>
#import "baomuDelegate.h"
@interface Morther:NSObject<NSCopying>
{
    //一直以来,委托的类型一直使用id类型。
    id <baomuDelegate> baomu;//此处声明一个代理人,从而mother可以让代理人完成需要代理的事情
}
//委托也可以作为属性申明,一般使用assign!!
//@property(nonatomic, assign)id<baomuDelegate> Delegate;
//在ARC下,使用@property(weak)id<baomuDelegate> Delegate;
@property(nonatomic, copy)NSString *bobyName;
- (void) delegatething:(int)i;
- (instancetype)initWithName:(NSString *)BobyName;

//使用@property属性生成的方法与下面一直
- (void) setDelegate:(id<baomuDelegate>) newBaomu; //设置代理人
- (id <baomuDelegate>)delegate;
@end



1 个回复

倒序浏览
实现文件:
#import "Morther.h"

@implementation Morther

//id<baomuDelegate>之间必须有挂号
- (void) setDelegate:(id<baomuDelegate>) newBaomu
{
    baomu = newBaomu;
}

//该方法返回参数类型为 id 必须遵守协议
- (id <baomuDelegate>)delegate
{
    return baomu;
}

- (instancetype)copyWithZone:(NSZone *)zone
{
    Morther *newMorther = [[Morther allocWithZone:zone] init];
    newMorther.bobyName = _bobyName;
    return newMorther;
}
- (instancetype)initWithName:(NSString *)BobyName
{
    self = [super init];
    if (self) {
        self.bobyName = BobyName;

    }
    return self;
}
- (void) delegatething:(int)i
{
    switch (i) {
        case 1:
            [baomu takeEat];
            break;
        case 2:
            [baomu takePlay];
            break;
        case 3:
            [baomu takeShower];
            break;
        case 4:
            [baomu takeSleep];
            break;
        default:
            break;
    }
}

@end

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马