iOS開發學習筆記:基礎知識之代理模式之老王的故事

蘆葦科技App技術團隊發表於2019-01-13

iOS開發學習筆記:基礎知識之代理模式之老王的故事

設計模式在各個領域都得到廣泛應用,是在特定場景下對特定問題的解決方案,這些解決方案都是經過反覆的論證測試而總結出來的。

在接觸到專案時,很多地方都會使用到設計模式。而這段時間的專案需要用到代理較多,而本人對代理設計模式還比較模糊,故本文會從自身學習過程來說,主要解析代理的一些知識。

首先是一些概念

在專案中需要進行訊息傳遞,接觸得比較多的是傳值、傳事件:

  • 傳值:常用於A類要把自己的一個資料或者物件傳到B類,讓B類去處理。
  • 傳事件:A類發生了什麼事,要把這件事告訴委託的物件,由他去進行反應。

而在iOS中有很多訊息傳遞方式,簡單列舉有:

  • 通知:看名稱比較好理解,是一種一對多的訊息傳遞方式,是由通知中心對訊息進行接收和廣播。
  • block:可以將回撥處理程式碼直接寫在block程式碼塊中。
  • KVO:Category—NSKeyValueObserving,通過屬性監聽的方式來檢測某個值的變化,當值發生變化時呼叫KVO的回撥方法。
  • target action:通過將物件傳遞到另一個類中,在其中將該物件當做target的方式來呼叫物件方法,從記憶體角度來說與代理類似。
  • 代理:是一種通用的設計模式,iOS中對代理支援的很好,由代理物件、委託者、協議三部分組成。

其實在學習到代理之前,用的 target action 比較多,它只有一個引數,並且無返回值的,場景適用於單個事件,主要用於系統的類中。而代理可以有多個引數,可以有 BOOL 型別的返回值,來確定是否可以執行下一個方法。能處理多個事件,經常用於自己設計的程式中。

代理是一種通用的設計模式,有特定的語法來實現,主要由三部分組成:

  • 協議:規定代理雙方的行為
  • 委託:委託方,指定代理去完成什麼
  • 代理:接受委託方 or 委託物件,完成委託方需要實現的事

協議是什麼:

顧名思義就是要遵循的規則。在協議中定義了一些方法,如果代理想要實現這個協議中的一系列方法,就必須遵守這個協議。這也說明這種模式是單向的,訊息的傳送方(委託方) 需要知道接收方(代理方)是誰,即只需要知道它的代理方是否遵守了協議反過來是不需要的。利用協議可以進行物件之間的相互通訊,還可將資料與業務邏輯解耦。

協議有兩種模式:

  • 委託模式:資訊通過協議中的方法引數從委託方流向代理方,或者事件發生時,委託者通知代理者 ,簡單表述為:委託方傳遞資訊或者事件到代理方。
  • 資料來源模式:資料來源模式的資訊流向與委託模式正好相反,委託方需要從代理方拉取資料。 簡單表述為:代理方傳遞資訊到委託方。

從簡單的例子出發

先設定情景:我有個朋友阿白,他家同一棟樓的鄰居是個身材很好的漂亮妹子小藍,最近天氣那麼冷,還是能看到小藍經常在屋子裡跑跑跳跳。朋友納悶啊,是不是她家裡的空調壞了,要運動來發保持身體熱量啊。阿白天生熱心腸,想去幫小藍看看空調壞沒壞。但是他害羞啊,只能找人幫他去看看,他想到了在網上釋出告示招人,便發帖,上面寫著“阿白招跑腿之行動指南——從我家去到妹子小藍家”,能做到這件事的都可以來。老王手速最快,態度最積極,所以我就拿老王跑腿的事來做範例。

這個例子是基於 MVC 設計模式的。

這裡,

阿白就是委託( HomeOfMyFriend 檔案),

老王就是代理( ViewController 檔案),

帖子內容就是協議,裡面寫的內容就是老王走去妹子家這件事。

先寫協議和委託

HomeOfMyFriend.h 中:

  • 阿白首先要寫協議,協議要寫協議名和內容吧(也就是方法),待會兒老王要遵循這個協議,執行這個方法的。So,用當前頁面檔名+Delegate作為協議名,並列出方法。

iOS開發學習筆記:基礎知識之代理模式之老王的故事

  • 有了這個協議以後,那麼就需要用一個屬性來存放委託物件了。這個屬性需定義成 weak ,而不是用 strong ,如果使用 strong ,委託方持有委託物件,委託物件也會持有委託方,兩個物件之間都是強應用,形成你中有我,我中有你的關係,就會形成迴圈引用(retain circle) 造成這兩個物件無法銷燬。

iOS開發學習筆記:基礎知識之代理模式之老王的故事

HomeOfMyFriend.m 中:

  • 然後老王來到阿白家,阿白給了指令以後老王才會出發,執行從阿白家到妹子家這件事。

HomeOfMyFriend.m 中,我會以點選事件 @selector(WangGo) 來代表阿白指派老王出發。

iOS開發學習筆記:基礎知識之代理模式之老王的故事

再寫代理

ViewController.m

  • 老王要遵守協議,所以在 ViewController.m 中,要繼承協議。

iOS開發學習筆記:基礎知識之代理模式之老王的故事

  • 老王作為行動者、代理方,當然還要對協議中的方法進行實現

iOS開發學習筆記:基礎知識之代理模式之老王的故事

  • 然而我們要在 ViewController.mHomeOfMyFriend 的例項中註冊 delegate 才行。

註冊 delegate 是什麼意思呢?故事內描述出來,就是:註冊 delegate 後,老王才得以表明身份,在小藍門前“咚咚咚”敲門說:“小藍呀,我是受你鄰居阿白委託來看你的,你不要害怕,讓我進去吧~”。

iOS開發學習筆記:基礎知識之代理模式之老王的故事

故事就在我朋友阿白髮出指令“老王Go!”(點選按鈕,觸發 WangGo 方法),老王心急火燎馬不停蹄從阿白家去到小藍家(從 HoneOfMyFriend 跳轉到 XiaoLanHouseController )的唯美畫面中,結束啦!


本渣故事、小栗子可能是一個再普通不過的實現,其實也是我學習路上曾經花了挺多時間去理解的一個地方,本意是為了加深對代理模式某一功能、某一方面的理解,若有幸能給各位看官大佬們帶來一點幫助或者是一絲絲笑意,或者能得到一些指導指正,對本菜鳥來說就是莫大的樂事了!

相關文章