在前一篇文章我们介绍了OC中的协议的概念,这篇文章我们就来介绍一下OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的。

这里举一个简单的例子:

小孩类,护士类,保姆类,其中小孩类有两个方法:wash和play

这里代理对象就是:护士类、保姆类,小孩类是被代理对象。

看一下代码:

首先看一下小孩类:

Children.h

 1 //  
 2 //  Children.h  
 3 //  12_DesignStyle  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #import <Foundation/Foundation.h>  
10   
11 @class Children;//如果没有这行代码的话,协议ChildrenDelegate中得Children类型就会查找不到,报错  
12   
13 @protocol ChildrenDelegate <NSObject>  
14   
15 @required  
16 - (void)wash:(Children *)children;  
17 - (void)play:(Children *)children;  
18   
19 @end  
20   
21 @interface Children : NSObject{  
22       
23     //Nure *_nure;//保姆  
24     //这里可以使用多态技术实现,因为保姆,护士有共同的父类NSObject,但是这里不使用这种方式,而是使用id类型  
25     //但是我们还需要为这个类型添加一些方法,这里就用到了协议  
26     //这个代理对象必须遵从ChildrenDelegate协议  
27     id<ChildrenDelegate> _delegate;//这个变量就是小孩的代理对象  
28     NSInteger timeValue;  
29 }  
30   
31 -(void)setDelegate:(id)delegate;  
32   
33 @end  

这里,我们定义了一个协议:ChildrenDelegate,他有两个必要的方法:wash和play。

我们还定义了一个很重要的属性:

_delegate

这个属性定义有点不一样,这个就是实现代理对象的精髓所在了,id是不确定类型,所以这个_delegate变量可以被赋值为的类型是:只要实现了ChildrenDelegate协议的类就可以了。这里就记住了,以后这种定义方法后面会用到很多。相当于Java中的接口类型,只能赋值其实现类的类型。只是这里的定义格式为:id<协议名>

然后就是一个设置协议的方法了,注意参数类型也必须是id的。

其实这里面也牵涉到了之前说到的多态特性,所以说代理模式也是建立在多态的特性上的。

Children.m

 1 //  
 2 //  Children.m  
 3 //  12_DesignStyle  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #import "Children.h"  
10   
11 //这里用到了保姆的一些动作  
12 //假如现在想请一个护士,那么我们又要去从新去请一个护士,那么这里面代码需要改,把保姆的地方换成护士的地方  
13 //产生的原因就是因为耦合度太高了,保姆和孩子耦合在一起,如果需要换的话,就需要改动代码  
14 //  
15 @implementation Children  
16   
17 - (id)init{  
18     self = [super init];  
19     if(self != nil){  
20         [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];  
21     }  
22     return self;  
23 }  
24   
25 -(void)setDelegate:(id)delegate{  
26     _delegate = delegate;  
27 }  
28   
29 - (void)timerAction:(NSTimer *)timer{  
30     timeValue++;  
31     if(timeValue == 5){  
32         [_delegate wash:self];  
33     }  
34     if(timeValue == 10){  
35         [_delegate play:self];  
36     }  
37 }  
38   
39 @end

我们自定义了一个初始化方法,在初始化方法中我们做了一个定时器的工作。

1 [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];  

这个就是OC中启动一个简单的计时器:每隔1s中就去执行一次self中的timerAction方法。

OC中的定时器和java不一样,他的执行逻辑可以单独的在一个指定的方法中去做(C中的函数指针差不多,只要传递一个函数指针过来,就可以执行指定的函数,所以@selector做的工作就是这个),但是Java中必须实现Runable接口,在run方法中执行指定的逻辑代码。

在timerAction方法中,我们是判断当时间到5s了,就执行代理对象的wash方法,10s的时候执行play方法。

在来看一下护士类:

Nure.h

 1 //  
 2 //  Nure.h  
 3 //  12_DesignStyle  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #import <Foundation/Foundation.h>  
10   
11 #import "Children.h"  
12   
13 @interface Nure : NSObject<ChildrenDelegate>  
14   
15 - (void)wash:(Children *)children;  
16 - (void)play:(Children *)children;  
17   
18 @end  

护士类很简单,实现ChildrenDelegate协议。 

Nure.m

 1 //  
 2 //  Nure.m  
 3 //  12_DesignStyle  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #import "Nure.h"  
10   
11 #import "Children.h"  
12   
13 @implementation Nure  
14   
15 - (void)wash:(Children *)children{  
16     NSLog(@"小孩脏了,保姆帮小孩洗澡");  
17 }  
18   
19 - (void)play:(Children *)children{  
20     NSLog(@"小孩哭了,保姆和小孩玩耍");  
21 }  
22   
23 @end

在这里就去实现wash和play方法了。

来看一下保姆类:

Nanny.h

 1 //  
 2 //  Nanny.h  
 3 //  12_DesignStyle  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #import <Foundation/Foundation.h>  
10   
11 #import "Children.h"  
12   
13 @interface Nanny : NSObject<ChildrenDelegate>  
14   
15 - (void)wash:(Children *)children;  
16 - (void)play:(Children *)children;  
17   
18 @end 

Nanny.m

 1 //  
 2 //  Nanny.m  
 3 //  12_DesignStyle  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #import "Nanny.h"  
10   
11 #import "Children.h"  
12   
13 @implementation Nanny  
14   
15 - (void)wash:(Children *)children{  
16     NSLog(@"小孩脏了,护士帮小孩洗澡");  
17 }  
18   
19 - (void)play:(Children *)children{  
20     NSLog(@"小孩哭了,护士和小孩玩耍");  
21 }  
22   
23 @end 
 

保姆类和护士类的代码逻辑是一样的,因为他们两个都是实现了一个协议。

测试类:

main.m

 1 //  
 2 //  main.m  
 3 //  12_DesignStyle  
 4 //  
 5 //  Created by jiangwei on 14-10-11.  
 6 //  Copyright (c) 2014年 jiangwei. All rights reserved.  
 7 //  
 8   
 9 #import <Foundation/Foundation.h>  
10   
11 #import "Children.h"  
12 #import "Nure.h"  
13 #import "Nanny.h"  
14   
15 //核心:id类型+协议  
16 //做到低耦合操作  
17 //同时也可以做到两个类之间的通信  
18   
19 int main(int argc, const charchar * argv[]) {  
20     @autoreleasepool {  
21         Children *child = [[Children alloc] init];  
22           
23         Nure *nure = [[Nure alloc] init];  
24         Nanny *nanny= [[Nanny alloc] init];  
25           
26         [child setDelegate:nanny];  
27 //      [child setNure:nure];  
28           
29         [[NSRunLoop currentRunLoop] run];  
30     }  
31     return 0;  
32 }  

看到了,测试类很简单。我们也发现了,代理模式的好处也是显现出来了,比如现在又来了一个人来照顾孩子:妈妈类,那么我们只要让妈妈类实现那个协议即可。这种耦合度也不会很高。所以代理模式还是超级有用的,而且我们后面在开发IOS的时候,会发现他里面用到的代理模式很多的。

运行结果:




总结

这一篇就介绍了OC中如何实现代理模式,其实OC中的代理模式核心技术是:id类型+协议+多态。

posted on 2015-01-03 12:35  I.L.L  阅读(253)  评论(0编辑  收藏  举报