首页 > 代码库 > [程序示例]Objective-C中的委托设计模式(牛仔与姑娘)

[程序示例]Objective-C中的委托设计模式(牛仔与姑娘)

       今天整理电脑翻到以前自学Objective-C时写的一个练习委托设计模式的一个小程序,就po上来和大家分享,顺便自己也复习一下OC中的委托。

       Objective-C中的委托设计模式是和协议分不开的。

       协议呢,就是使用了这个协议后就要按照这个协议来办事,协议要求实现的方法就一定要实现。(在Objective-C2.0中可以在协议里选择是否必须实现某种方法,用关键字@optional和@required)

       委托的话,顾名思义就是自己处理不了的事情,委托他人按照协议里写好的条款来办理这件事。

具体实现的步骤可以按照下面这样:

       1.拟定一份协议,协议里包括了想要实现的事情(即方法)。

       2.委托人类中设置一个遵守该协议的委托变量。

       3.被委托人类中实现协议要求的方法。

       4.把委托人中的委托变量设置成被委托人。

       5.当事情发生时,用委托变量调用被委托人中的协议方法。


下面讲讲我写的这个例程,牛仔与姑娘。

       故事背景是,在联邦政府还没有进入的荒野西部,一个善良美丽的姑娘Lucy和父亲相依为命,过着艰苦但是还算幸福的生活。一天,一群土匪强盗的到来带走了Lucy的父亲,Lucy伤心至极,便委托好心的牛仔John Marston去解救他的父亲,并将这群恶棍绳之以法。正义驱使John接下了这个活,并最终解救了Lucy的父亲,并惩治了坏蛋。

       

        好了,首先我们得先创建一份协议Wanted,包含两个方法,saveHerDad和killTheBadGuy,代码如下:

#import <Foundation/Foundation.h>

@protocol Wanted <NSObject>
@required

-(int)saveHerDad;
-(void)killTheBadGuy;

@end
       接着,创建姑娘Girl类,在其中设置一个遵守Wanted协议的委托变量,使用helpHelp方法来触发事件,我用了定时器来模拟整个事件的发生,接口如下:

#import <Foundation/Foundation.h>
#import "Wanted.h"
@interface Girl : NSObject
{
}
@property(nonatomic,copy) NSString *name;
@property(nonatomic,assign) id <Wanted> delegate;

-(id)initWithName:(NSString*)name WithDelegate:(id<Wanted>) delegate;
-(void)helpHelp;   

@end
       实现如下:
#import "Girl.h"
#import "Cowboy.h"

@interface Girl ()

-(void)seesTheCowboy:(NSTimer *)timer;

@end

@implementation Girl

-(id)initWithName:(NSString*)name WithDelegate:(id<Wanted>) delegate{
    self = [super init];
    if (self) {
        self.name = name;
        self.delegate = delegate;
    }
    return self;
}

-(void)helpHelp{
    NSLog(@"%@:My name is %@,my dad was taken by the bad guys,can you save him,please?",self.name,self.name);
    NSLog(@"%@:OK,young lady,wait for the good news!",self.delegate);
    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(seesTheCowboy:) userInfo:@"My dad" repeats:YES];
}

-(void)seesTheCowboy:(NSTimer *)timer{
    if ([self.delegate respondsToSelector:@selector(saveHerDad)]) {
        int i = [self.delegate saveHerDad];
        if (i==0) {
            NSLog(@"%@:My heart is so broken,I cant live without him,you must save him please,woo woo.",self.name);
            printf("\n");
        }else{
            NSLog(@"%@:Thank you so much,marry me~",self.name);
            [timer invalidate];
        }       
    }
}

@end
       然后,创建牛仔Cowboy类,用他来实现协议Wanted中的方法,由于不想让外部调用协议中的方法,所以我们将协议中的方法设置为私有方法,接口如下:

#import <Foundation/Foundation.h>

@interface Cowboy : NSObject

@property (nonatomic,copy) NSString *name;


@end

       实现如下:

#import "Cowboy.h"

@implementation Cowboy
static int result;
-(int)saveHerDad{
    printf("\n");
    result = [self killTheBadGuy];
    if (result == 0) {
        NSLog(@"%@:There are too many of'em,I'll take all of my men and kill them all!!!Wait for the good news!",self.name);
        result++;
        return 0;       
    }else{   
        NSLog(@"%@ and his crew:I killed all the bad guys,and here is your father.",self.name);
        return 1;
    }
}
     
-(int)killTheBadGuy{
    return result;
}
-(NSString *)description {
    NSString *name = self.name;
    return name;
}
@end
       

       好了,接下来我们就开始等着事件发生了,我设置了定时器,两秒触发一次,当result值为0的时候,营救并不成功,我们的牛仔铩羽而归;当result值为1时,营救任务成功,解救了Lucy的父亲。主函数登场:

#import <Foundation/Foundation.h>
#import "Girl.h"
#import "Cowboy.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {        
        Cowboy *cowboy = [[Cowboy alloc] init]; //创建Cowboy实例
        cowboy.name = @"John Marston";          
        Girl *girl = [[Girl alloc] initWithName:@"Lucy" WithDelegate:cowboy]; //初始化girl,将cowboy作为委托人
        [girl helpHelp];   //触发时间
                
        NSDate *date = [NSDate date];
        //设置定时器,程序共运行6秒
       [[NSRunLoop currentRunLoop] runUntilDate:[date dateByAddingTimeInterval:6]];
    }
    return 0;
}

       一切都准备就绪,现在让我们的牛仔拿起枪,行动起来吧!

       编译成功!输出结果如下:

2014-07-16 17:27:10.973 Girl&Cowboy[4055:303] Lucy:My name is Lucy,my dad was taken by the bad guys,can you save him,please?

2014-07-16 17:27:11.012 Girl&Cowboy[4055:303] John Marston:OK,young lady,wait for the good news!


2014-07-16 17:27:13.014 Girl&Cowboy[4055:303] John Marston:There are too many of‘em,I‘ll take all of my men and kill them all!!!Wait for the good news!

2014-07-16 17:27:13.015 Girl&Cowboy[4055:303] Lucy:My heart is so broken,I cant live without him,you must save him please,woo woo.



2014-07-16 17:27:15.014 Girl&Cowboy[4055:303] John Marston and his crew:I killed all the bad guys,and here is your father.

2014-07-16 17:27:15.015 Girl&Cowboy[4055:303] Lucy:Thank you so much,marry me~

Program ended with exit code: 0

       

       我们的英雄把姑娘的父亲救出来了并且杀死了坏人!

       这个例子很简单,实际应用中会比这个复杂得多,但是希望通过我这个例子能让不了解的同学对委托设计模式有个初步的认识吧~吐舌头