閉包, 代理和通知的區別?


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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章