delegate
優(yōu)點:
- 語法嚴格, 所有監(jiān)聽的事件必須是在 delegate 協(xié)議中有清晰的定義
- 如果 delegate 中的一個方法沒有實現(xiàn)那么就會出現(xiàn)編譯警告/錯誤
- 協(xié)議必須在 controller 的作用域范圍內(nèi)定義
- 在一個應用中的控制流程是可跟蹤的并且可識別的
- 在一個控制器中可以定義多個不同的協(xié)議, 每個協(xié)議有不同的 delegates
- 沒有第三方對象要求保持/監(jiān)視通訊過程
- 能夠接收調(diào)用的協(xié)議方法的返回值. 這意味著 delegate 能夠提供反饋信息給controller
- 經(jīng)常被用在存在父子關系的對象之間的通信, 例如控制器和控制器的 View
缺點
- 需要定義很多代碼: 1.協(xié)議定義:2.Controller的delegate屬性:3.在delegate本身中實現(xiàn)delegate方法定義
- 在釋放代理對象時, 需要小心的將delegate改為nil. 一旦設定失敗,那么調(diào)用釋放對象的方法將會出現(xiàn)內(nèi)存 crash
- 在一個 Controller 中有多個 delegate 對象, 并且 delegate hi是遵守同一個協(xié)議, 但還是很難告訴多個對象同一件事件.
- 經(jīng)常用在一對一的通信.
Notification
優(yōu)點
- 代碼量小, 實現(xiàn)簡單
- 對于一個發(fā)出的通知, 多個對象能做出反應, 即一對多的實現(xiàn)方式.
- Controller 能傳遞 Context 對象, Context 對象存儲關于發(fā)送通知的信息.
缺點
- 編譯器不會檢查通知是否能夠被觀察證正確的處理
- 在釋放注冊的對象時, 需要在通知中心取消注冊
- 在調(diào)試的時候應用的工作以及控制過程很難跟蹤
- 需要第三方對象來管理Controller與觀察者對象之間的聯(lián)系
- controller 和觀察者需要提前知道通知名稱, UserInfo dictionary key. 如果這些沒有工作區(qū)間定義, 那么會出現(xiàn)不同步的情況:
- 通知發(fā)出后, Controller 不能從觀察者活得任何的反饋信息
KVO
優(yōu)點
- 能夠提供一種簡單的方法實現(xiàn)兩個對象間的同步.
- 能夠?qū)Ψ俏覀儎?chuàng)建的對象, 即內(nèi)部對象的狀態(tài)改變做出響應, 而且不需要改變內(nèi)部對象(SDK對象)的實現(xiàn)
- 能夠提供觀察的屬性的最新值以及先前值
- 用 key path 來觀察屬性, 因此也可以觀察嵌套對象
- 完成了對觀察對象的抽象, 因為不需要額外的代碼來允許觀察值能夠被觀察
- 可以一對多
缺點
- 我們觀察的屬性必須使用 string 來定義, 因此在編譯的時候不會出現(xiàn)警告和檢查
- 對屬性重構會導致我們的觀察代碼不可用
- 復雜的"IF"語句要求對象正在觀察多個值. 這是因為所有的代碼通過一個方法來指向.
- 當釋放觀察者時不需要移除觀察者
從設計模式的角度去分析 Delegate, Notification, KVO 的區(qū)別
- 效率方面 delegate 比 NSNotification高. delegate 方法比 notification 更加直接, 最典型的特征是, delegate 方法往往需要關注返回值, 也就是 delegate方法的結果.比如 windowShouldClose, 需要關系返回的是 YES 還是 NO. 所以deleagete方法往往包含 should 這個很傳神的詞. 也就是好比你做我的delegate, 我會問你我想關閉窗口你還愿意嗎? 你需要給我一個答案, 我根據(jù)你的答案來決定如何做下一步.相反的, notification 最大的特色就是不關心接受者的態(tài)度. 我直管把通告放出來, 你接受不接受就是你的事情, 同時我也不關心結果. 所以 notification 玩玩用 did 這個詞匯, 比如 NSWindowDidResizeNotification, 那么 NSWindow 對象放出這個 Notification 后就什么都不管了, 也不會等待接受者的反應.
- KVO 和 NSNotification 和 delegate 一樣, KVO 和 NSNotification 的作用也是類和類之間的通信, 和 delegate 不同的是
- KVO 和 NSNotification 都是負責發(fā)出通知, 剩下的事情就不管了, 所以沒有返回值
- delegate 只是一對一, 而這倆個可以一對多.
總結
什么是設計模式
- 設計模式是為特定場景下的問題而制定的解決方案. 特定場景指問題所在的重復出現(xiàn)的場景, 問題指特定環(huán)境下你先達成的目標. 同樣的問題在不同的環(huán)境下會有不同的限制和挑戰(zhàn). 定制的解決方案是指在特定環(huán)境下克服問題的限制條件而達成目標的一種設計
設計模式的分類
- 設計模式分為三種類型, 共 23 種
- 創(chuàng)建型模式: 單利模式, 抽象工廠模式, 建造者模式, 工廠模式, 原型模式.
- 結構型模式: 適配器模式, 橋接模式, 裝飾模式, 組合模式, 外觀模式, 享元模式, 代理模式.
- 行為型模式: 模板方法模式, 命令模式, 迭代器模式, 觀察著模式, 中介者模式, 備忘錄模式, 解釋器模式(interpreter模式), 狀態(tài)模式, 策略模式, 職責聯(lián)模式(責任鏈模式), 訪問者模式.
類工廠方法
- 類工廠方法的實現(xiàn)是為了向客戶提供方便, 他們將分配和初始化合在一個步驟中, 返回被創(chuàng)建的對象, 并進行自動釋放處理.
- 這些方法的形式是 + (type)className... (其中 className 不包括任何前綴)
- 工廠方法可能不僅僅為了方便使用. 他們不但可以將分配和初始化合在一起, 還可以為初始化過程提供對象的分配信息.
- 類工廠方法的另一個目的是使類(比如 NSWorkspace) 提供單利. 雖然 init... 方法可以確認一個類在每次程序運行過程中只存在一個實例, 但它需要首先分配一個"生的"實例, 然后還必須釋放該實例. 工廠方法可以避免為可能沒有用的對象盲目分配內(nèi)存.
單例
單例模式的意思就是只有一個實例. 單例模式確保摸一個類只有一個實例, 而卻自行實例化并像整個系統(tǒng)提供這個實例.
要點
- 一個類只能有一個實例
- 必須是自行創(chuàng)建的實例
- 必須自行向整個系統(tǒng)提供這個實例
優(yōu)點
-實例控制: singleton 會組阻止其他對象是實例化自己的 singleton 對象的副本, 從而確保所有對象都訪問唯一實例. - 靈活性: 因為類控制了實例化過程, 所以類可以更加靈活修改實例化過程.
手寫單例
static Class *class;
+ (Class *)shareInstance {
if(!class) {
static dispatch once_t Token;
dispatch_once (&token, ^ {
class = [[class alloc] init];
};
}
return class;
}
簡述觀察者模式,
- 觀察者模式 (Observer) 是一個或多個對象對另一個對象進行觀察, 當被觀察對象發(fā)生變化時, 觀察者可以直接或間接的得到通知, 從而能自動的更新觀察者的數(shù)據(jù), 或者進行一些操作.
- 具體到 iOS 的開發(fā)中, 實現(xiàn)觀察者模式常用的方式有 KVO 和 Notification 倆種.
- 倆者的不同在于, KVO是被觀察者主動向觀察者發(fā)送消息: Notification 是被觀察者向 NotificationCenter 發(fā)送消息, 再由 NotificationCenter post 通知到每個注冊的觀察者.
MVC,單例, 代理
- MVC: 就是 Model-View-Controller 的縮寫, M 指的是業(yè)務邏輯, V 指的是用戶界面, C 指的是控制器. MVC是架構模式, 是講 M 和 V 的代碼分離, 從而使同一個程序有不同的表現(xiàn)形式.
- 單例模式: 一個類只有一個實例
- 代理模式: 代理模式給某一個對象提供一個代理對象, 并由代理對象控制對源對象的引用, 比如一個工廠生產(chǎn)了產(chǎn)品, 并不想直接賣給用戶, 二十高了很多代理商, 用戶可以直接找代理商買東西, 代理商從工廠進貨, 常見的如QQ的自動回復就屬于代理攔截, 代理模式在 iphone 中得到廣泛應用.
測試, MVC 優(yōu)點不正確的是
A. 低耦合性
B. 高重用性和可適用性
C. 較低的聲明周期成本
D. 代碼高效率
- 參考答案: D
- 理由: MVC 只是一個鐘設計模式, 他的出現(xiàn)有比較久的歷史了. Model-Controller-View 是在開發(fā)中最常見到的設計模式, 通過將 Model, View, Controller 三者相互聯(lián)系, 以 Model 作為數(shù)據(jù)加工廠, 以 Controller 作為橋梁, 處理業(yè)務, 而 View 只是數(shù)據(jù)展示層, 理應與業(yè)務無關. MVC 設計模式降低了耦合性, 提供了重用性和適用性, 可以有效的提高開發(fā)效率.
MVVM
- MVVM 框架相對于傳統(tǒng)的 MVC 來說, 主要區(qū)別在于把原本在 C 中 (ViewController) 的業(yè)務邏輯, 網(wǎng)絡請求, 數(shù)據(jù)儲存等操作和表現(xiàn)邏輯, 分離到 ViewModel 中, 從而是 ViewController 得到精簡
- MVC 中, Controller 同時操作 Model 和 View; MVVM 中, ViewModel 作為一個過渡, Model 的數(shù)據(jù)獲取和加工由 ViewModel 負責, 得到適合 View 的數(shù)據(jù), 利用綁定機制, 使得 View 得以自動更新.
優(yōu)點:- 層次更加分明清晰
- 代碼簡潔優(yōu)雅
- 減少 VC 的復雜性
- 代碼和界面完全分離
- 方便測試
缺點: - MVVM 需要使用數(shù)據(jù)綁定機制, 對于 os x 開發(fā), 可以直接使用 cocoa Binding, 對于 iOS , 沒有太好的數(shù)據(jù)綁定方法, 可以使用 KVO, 但是如果需要綁定的屬性太多的話, 需要編寫大量的 Selector 代碼.
- reactiveCocoa 提供了一種很方便優(yōu)雅的綁定機制.
ReactiveCocoa
- RAC 具有函數(shù)式編程和響應式鞭策的特性
- 視圖解決以下問題
- 傳統(tǒng) iOS 開發(fā)過程中, 狀態(tài)以及狀態(tài)之間依賴過多的問題
- 傳統(tǒng) MVC 架構的問題: Controller 比較復雜, 可測試性差
- 提供統(tǒng)一的消息傳遞機制
ViewController瘦身
- 把 Data Source 和其他 Protocols 分離出來 (將 UITableView 或者 UICollectionView 的代碼提取出來放在其他類中)
- 將業(yè)務邏輯移到 Model 中 (和模型有關的邏輯全部在 Model 中寫)
- 把網(wǎng)絡請求邏輯轉(zhuǎn)移到 Model 層 (網(wǎng)絡請求依靠模型)
- 把 View 代碼移到 View 層 (自定義View)
項目里使用的設計模式
- 單利設計模式: UIApplication, NSUserDefaults, 是蘋果封裝的單利. 在項目中經(jīng)常會將用戶數(shù)據(jù)管理封裝成一個單利類, 因此用戶的信息需要全局使用.
- MVC 設計模式: 現(xiàn)在卻大部分項目都是基于 MVC 設計模式的, 現(xiàn)在有一部分開發(fā)者采用 MVVM, MVP 等模式.(MVP 中的 P 即為 Presenter:作為model和view的中間人硅蹦,從model層獲取數(shù)據(jù)之后傳給view尊搬,使得View和model沒有耦合耐朴。)
- 通知(NSNotification)模式: 通知在開發(fā)是必不可少的, 對于跨模塊的類交互, 需要使用通知, 對于多對多的關系, 使用通知更好的實現(xiàn). (頁面跳轉(zhuǎn), 夜間模式什么的)
- 工廠設計模式: 其中生成控件的 API, 都已經(jīng)封裝成一套, 全部是擴展的類方法, 可以簡化很多代碼
- KVC / KVO 設計模式: 有時候需要監(jiān)聽某個類屬性值的變化而做出響應的變化, 當變化時, 需要更新UI顯示, 這個時候使用 KVC / KVO 設計模式就很方便了
如何實現(xiàn)單例
- 用 GCD dispatch_one 來創(chuàng)建, 保證單例只會創(chuàng)建一次. 如果不小心銷毀了, 在調(diào)用方法不會創(chuàng)建.
注意: 實際開發(fā)中不會去重寫內(nèi)存管理方法, 單例一旦創(chuàng)建, 整個 App 使用的過程都不會釋放, 占用內(nèi)存, 所以可以濫用.