1. 閉包: 就是block, 在swift中叫做閉包
block是iOS4.0+ 和Mac OS X10.6+ 引進的C語言的擴展, 用來實現匿名函數的特徵
blocks語法塊代碼以閉包的形式將各種內容進行傳遞, 可以是代碼, 可以是數組, 什麼都可以
block是一個數據類型, 存放一段代碼, 編譯的時候不會執行, 只有用到的時候纔會去執行裏面的代碼. 聲明的時候使用 copy 是因爲要從棧區拷貝到堆區, 在棧區會受到作用域的限制, 超出所在的函數就會被銷燬, 就沒辦法進行傳值回調等一系列操作了.
閉包是能夠讀取其他函數內部變量的函數, 在一段連續請求代碼中可以清晰的看到調用參數 (比如發送請求) 和響應結果. 所有采用block能夠抽取出很多公共函數, 大大提高了代碼的可讀性, 可維護性, 封裝性
> 最常見的使用場景: 數據請求回調
> 使用注意: 注意防止 循環引用
ARC下使用__weak來修飾, MRC下使用__block來修飾(如果一個變量在 block 外部創建, 需要在 block 內部修改, 那麼需要使用 block 修飾這個變量, block 可以再 ARC 和 MRC 情況下使用, 可以修飾對象和基本數據類型, weak 只能在 ARC 下使用, 只能修飾對象, 不能修飾基本數據類型)
2. 代理: 一對一, 對用一個協議, 一個對象只能設置一個代理delegate
> 使用步驟:
1) 委託方聲明協議定義代理方法
2) 在委託方判斷代理方有沒有實現代理方法
3) 代理方遵守協議設置代理事項代理方法
> 注意:
1) 單利對象不能用代理
2) 代理執行協議方法時要使用responds ToSelector檢查代理是否符合協議(檢查對象能否響應指定消息), 避免代理回調時因爲沒有實現代理方法而造成的崩潰
> 使用場景: 比如方法較多時可以選擇delegate進行解耦
3. 通知: 一對一, 一對多傳值
> 使用步驟:
1) 發送通知
2) 監聽通知
3) 移除通知
4) 實現通知的監聽方法
> 使用場景: 比如相隔多層的兩個控制器之間跳轉
> 注意:
1) 一旦接受消息的對象多了, 就難以控制了, 可能有你不希望的對象接受了消息並做了處理
2) 創建了監聽者, 要在dealloc裏面移除, swift裏面在deinit中移除
> 下面我們來做詳細的對比
從效率來說delegate和block都要比NSNOtification高, NSNOtification是重量級的, 開發中根據實際情況做具體選擇
1) delegate和block一般都是一對一的通信
2) delegate需要定義協議方法,實現協議方法, 並且要建立代理關係纔可以通信, block更加簡潔, 但通信時間較多的話,建議使用delegate
3) delegate運行成本低, block成本高
block出棧要把使用的數據從棧內存copy到堆內存, 當然對象的話就是加計數, 使用完或者block置nil後才消除; delegate只是保存了一個對象指針, 直接回調, 沒有額外消耗
4) delegate注重過程信息的傳輸: 比如發起一個網絡請求, 可能想要知道此時請求是否已經開始, 是否收到了數據, 數據是否已經接收完成, 數據接收失敗
block注重結果傳輸: 比如網絡請求數據, 只知道成功或者失敗就可以了, 並不需要知道進行了多少或者額外的一些信息
5) block更清晰. 比如一個viewController中有多個事件, delegate需要對每個事件進行判斷識別來源. 而block可以在創建事件的時候區分開來. 這也是爲什麼蘋果官方建議更多的使用block而不是delegate