代理擴展-隱式代理和多播代理

来源:http://www.cnblogs.com/panda1024/archive/2016/11/04/6031619.html
-Advertisement-
Play Games

代理這東西,真的不想再談了,估計是個iOS開發人員都能熟練使用,跟Notification和Block一樣,都用的滾瓜爛熟了。 這裡小小的談論一下代理的擴展:隱式代理和多播代理,其實非常簡單。 隱式代理:就是定義協議的屬性時不用再遵守協議了,實現方法的類也不用在遵守協議了,因為協議方法定義在NSOb ...


代理這東西,真的不想再談了,估計是個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、通知的參數通過UserInfo來傳遞,UserInfo是一個字典,也容易寫錯;

3、通知是單向的,代理是雙向的,有返回值;

4、通知的邏輯不清晰。

思路:其實就是定義一個代理屬性,只不過這個代理屬性是一個數組而已,然後對外提供一個方法添加元素至這個數組中。然後調用對象方法的時候,迴圈遍歷這個屬性(數組類型)即可。理解了這點,也就很輕鬆了。

說了這麼多,說的我自己都迷糊了,不如直接上代碼來的痛快。反正代碼很少,就不解釋了。

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呢。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.SwipeRefreshLayout是Google在support v4 19.1版本的library更新的一個下拉刷新組件,實現刷新效果更方便。 弊端:只有下拉 2.在xml文件中引用android.support.v4.widget.SwipeRefreshLayout控制項,在裡面可以放置任 ...
  • 1、Android Log簡介; 在程式中輸出日誌,使用 android.util.Log 類。該類提供了若幹靜態方法: Log.v(String tag, String msg); // 任何消息都會輸出 Log.d(String tag, String msg); // 僅輸出debug調試的意 ...
  • 1.簡介 RecyclerView是一種新的視圖組,目標是為任何基於適配器的視圖提供相似的渲染方式。它被作為ListView和GridView控制項的繼承者,在最新的support-V7版本中提供支持。RecyclerView架構,提供了一種插拔式的體驗,高度的解耦,異常的靈活,通過設置它提供的不同L ...
  • 近日工作不是太忙,剛好有時間瞭解一些其他東西,本來打算今天上午去體檢,但是看看天氣還是明天再去吧,也有很大一個原因:就是周六沒有預約上!閑話少說,這裡簡單對鎖來個簡單介紹分享。 ...
  • 如果想讓別人用你的代碼但是又不想暴露你的源碼,可以使用靜態庫的方式 1.新建項目選擇Cocoa Touch Static Libraay 2.把要打包的文件拖入工程裡面 3.選擇targets->Build Phases->點擊加號->選擇New Headers Phase 4.在Headers裡面 ...
  • 開源一個即時通訊類App,支持純文本、語音、地理位置、圖片聊天,同時還加入了好友圈功能,支持分享動態和發送圖片,支持搜索附近的人,使用的百度地圖定位功能;由Bmob後端雲提供伺服器支持,歡迎喜歡的伙伴在我的github上面start和fork。項目地址:https://github.com/tony ...
  • 隊列組 讓隊列里的任務同時執行,當任務都執行完畢時,再以通知的形式告訴程式員。舉例,同時下載兩張圖片,兩張圖片都下載完了,在合成成一張。 代碼: 日誌 效果: 如果不用隊列組,下載第一張圖片、下載第二張圖片、合併兩張圖片,就只能當做一個任務放入隊列中,不能同時下載兩張圖片,耗時幾乎多了一倍。因為,如 ...
  • 說起鏈式編程和函數式編程,小伙伴們千萬不要緊張。 聽著很高大尚,其實也就那麼回事。相信有過C#開發經驗的,或者其他編程經驗的,只要不是OC,一看就知道。 看兩行代碼: 上面的就是鏈式編程+函數式編程。 來個大白話解釋:看到括弧裡面的參數了吧,跟C的函數調用是不是很相似,包括別的語言,都用小括弧傳參, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...