代理扩展-隐式代理和多播代理

Posted 小课桌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代理扩展-隐式代理和多播代理相关的知识,希望对你有一定的参考价值。

代理这东西,真的不想再谈了,估计是个ios开发人员都能熟练使用,跟Notification和Block一样,都用的滚瓜烂熟了。

这里小小的谈论一下代理的扩展:隐式代理和多播代理,其实非常简单。

 

隐式代理:就是定义协议的属性时不用再遵守协议了,实现方法的类也不用在遵守协议了,因为协议方法定义在NSObject的分类中。

直接上代码吧,真的是十分的简单:

1、Person类的头文件:

 1 #import <Foundation/Foundation.h>
 2 
 3 /**
 4  NSObject的一个分类,里面声明(代理)方法
 5  */
 6 @interface NSObject(myfenlei)
 7 
 8 - (void)eat;
 9 
10 @end
11 
12 /**
13  定义一个类
14  */
15 @interface Person : NSObject
16 
17 @property(nonatomic,copy) NSString *name;
18 
19 /**
20  代理属性,不用尊守协议,因为要实现的是NSObject分类的方法
21  */
22 @property(nonatomic,weak) id delegate;
23 
24 - (void)run;
25 
26 @end

2、Person类的.m文件:

 1 #import "Person.h"
 2 
 3 @implementation Person
 4 
 5 - (void)run{
 6     NSLog(@"%@在跑步",self.name);
 7     
 8     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 9         if([self.delegate respondsToSelector:@selector(eat)]){
10             // 调用代理对象的eat方法(声明在NSObject的分类里面)
11             [self.delegate eat];
12         }
13     });
14 }
15 
16 @end

3、控制器中调用Person对象的run方法,run方法里面调用代理方法:

 1 #import "ViewController.h"
 2 #import "Person.h"
 3 
 4 @interface ViewController ()
 5 
 6 @end
 7 
 8 @implementation ViewController{
 9     Person *_per;
10 }
11 
12 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
13     _per = [[Person alloc] init];
14     _per.name = @"小明";
15     _per.delegate = self; // 指定代理
16     [_per run]; // 调用方法,方法里面调用代理方法
17 }
18 
19 /**
20  实现协议方法
21  */
22 - (void)eat{
23     NSLog(@"跑完了,准备吃饭呢");
24 }
25 
26 @end

完事了,没有了。隐式代理就是这么的简单。其中强调一下,最最最重要的是协议方法定义在了NSObject的分类中。理解了这点,是不是很easy呢。

 

下面:我们再来谈谈多播代理。

多播代理和通知很像,一个对象发出消息,多个对象监听。但比通知好用:1、通知的Key容易写错;2、通知的逻辑不清晰。

思路:其实就是定义一个代理属性,只不过这个代理属性是一个数组而已,然后对外提供一个方法添加元素至这个数组中。然后调用对象方法的时候,循环遍历这个属性(数组类型)即可。理解了这点,也就很轻松了。

说了这么多,说的我自己都迷糊了,不如直接上代码来的痛快。反正代码很少,就不解释了。

1、Person类头文件:

 1 #import <Foundation/Foundation.h>
 2 
 3 /**
 4  定义协议,声明方法
 5  */
 6 @protocol PersonDelegate <NSObject>
 7 
 8 - (void)eatSomething;
 9 
10 @end
11 
12 
13 @interface Person : NSObject
14 
15 /**
16  添加代理的方法
17 
18  @param delegate <#delegate description#>
19  */
20 - (void)addDelegate:(id)delegate;
21 
22 - (void)eat;
23 
24 @end

2、Person类.m文件:

 1 #import "Person.h"
 2 
 3 @interface Person ()
 4 
 5 /**
 6  代理成员变量,是一个数组
 7  */
 8 @property (nonatomic, strong) NSMutableArray *delegates;
 9 
10 @end
11 
12 @implementation Person
13 
14 // 给代理数组添加元素
15 - (void)addDelegate:(id)delegate{
16     [self.delegates addObject:delegate];
17 }
18 
19 // 关键方法:调用对象方法时,遍历数组,今次执行方法
20 - (void)eat{
21     for (id delegate in self.delegates) {
22         [(id)delegate eatSomething];
23     }
24 }
25 
26 // 懒加载,初始化代理属性数组
27 - (NSMutableArray *)delegates{
28     if (_delegates == nil) {
29         _delegates = [NSMutableArray array];
30     }
31     return _delegates;
32 }
33 
34 @end

3、好了,接下来我们看看具体是怎么使用的:

 1     OneViewController *oneVc =[[OneViewController alloc] init];
 2     TwoViewController *twoVc = [[TwoViewController alloc] init];
 3     
 4     Person *per = [Person new];
 5     
 6     //设置多播代理
 7     [per addDelegate:oneVc];
 8     [per addDelegate:twoVc];
 9     
10     //调用代理方法
11     [per eat];

4、看到了吧,就是调用方法给代理属性(数组)中添加元素,然后调用eat方法时,遍历数组,执行方法。这里

OneViewController和TwoViewController都实现了协议里面的- (void)eatSomething;方法。
 1 // OneViewController
 2 #import "OneViewController.h"
 3 
 4 @interface OneViewController ()
 5 
 6 @end
 7 
 8 @implementation OneViewController
 9 
10 - (void)eatSomething{
11     
12     NSLog(@"one");
13 }
14 
15 @end
16 
17 // TwoViewController.
18 #import "TwoViewController.h"
19 
20 @interface TwoViewController ()
21 
22 @end
23 
24 @implementation TwoViewController
25 
26 - (void)eatSomething{
27     
28     NSLog(@"two");
29 }
30 
31 @end

好了,就是这样,是不是很easy呢。

 

以上是关于代理扩展-隐式代理和多播代理的主要内容,如果未能解决你的问题,请参考以下文章

swift 带有哈希表的多播代理

多播代理必须具有返回类型void。为什么?

简单委托(委托)与多播委托

Delphi的基于接口(IInterface)的多播监听器模式(观察者模式 ),利用RTTI实现Delphi的多播事件代理研究

UE4 C++代理(委托)

Forge Viewer - 如何在场景中访问(或获取渲染/片段代理)克隆的网格?