代理擴充-隱式代理和多播代理,代理擴充
代理這東西,真的不想再談了,估計是個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 @end11 12 /**13 定義一個類14 */15 @interface Person : NSObject16 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 @end11 12 13 @interface Person : NSObject14 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 @end11 12 @implementation Person13 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 @end16 17 // TwoViewController.18 #import "TwoViewController.h"19 20 @interface TwoViewController ()21 22 @end23 24 @implementation TwoViewController25 26 - (void)eatSomething{27 28 NSLog(@"two");29 }30 31 @end
好了,就是這樣,是不是很easy呢。