iOS開發筆記>> 代理模式是什麼?

代理模式就是我們經常說的代理設計模式, 也就是代理, 這也是iOS中一種消息傳遞的方式, 也可以通過這種方式來傳遞一些參數. 


代理是一種通用的設計模式, 由代理對象, 委託者, 協議三部分組成, 有特定的語法來實現代理模式, OC語言可以通過@Protocol實現協議


1. 代理主要由3部分組成: 

協議: 用來指定代理雙方可以做什麼, 必須做什麼

代理: 根據指定的協議, 完成委託方需要實現的功能

委託: 根據指定的協議, 指定代理去完成什麼功能



2. 代理實現流程: 

代理的本質就是代理對象內存的傳遞和操作, 在委託類設置代理對象後, 實際上只是用一個id類型的指針將代理對象進行了一個弱引用. 委託方讓代理方執行操作, 實際上是在委託類中向這個id類型指針指向的對象發送消息, 而這個id類型指針指向的對象就是代理對象. 


3. 代理原理:

 通過上圖我們發現, 其實委託方的代理屬性本質上就是代理對象自身, 設置委託代理就是代理屬性指針指向代理對象, 相當於代理對象只是在委託方中調用自己的方法, 如果方法沒有實現就會導致崩潰. 從崩潰信息來看, 就可以看出是代理方沒有實現協議中的方法導致的崩潰. 

而協議只是一種語法, 是聲明委託方中的代理屬性可以調用協議中聲明的方法, 而協議中方法的實現還是由代理方完成, 而協議方和委託方都不知道代理方有沒有完成, 也不需要知道怎麼完成


4. 代理內存管理:

爲什麼設置代理屬性都使用weak呢?

定義的指針默認都是__strong類型的, 而屬性本質上也是一個成員變量和set, get 方法構成的, strong類型的指針會造成強引用, 必定會影響一個對象的生命週期, 這也就會形成循環引用. 


4.1. 強引用

上圖中, 由於代理對象使用強引用指針, 引用創建的委託方loginVC對象, 並且成爲loginVC的代理. 這會導致loginVC的delegate屬性強引用代理對象, 導致循環引用的問題, 最終兩個對像都無法正常釋放. 

4.2. 弱引用

我們將LoginVC對象的delegate屬性, 設置爲弱引用屬性. 這樣在代理對象生命週期存在時, 可以正常爲我們工作, 如果代理對象被釋放, 委託方和代理對象都不會因爲內存釋放導致的Crash. 


4.3. 但是, 這樣還有點問題, 真的不會崩潰嗎?

有兩種方式弱引用代理對象, weak修飾的代理屬性和assign修飾的代理屬性, 前者在代理對像被釋放後不會導致崩潰, 而第二種會崩潰. 

weak和assign是一種"非擁有關係"的指針, 通過這兩種修飾符修飾的指針變量, 都不會改變被引用對象的引用計數. 但是在一個對象被釋放後, weak會自動將指針指向nil, 而assign則不會. 在iOS中, 向nil發送消息時會導致崩潰, 所以assign就會導致野指針的錯誤 unrecognized selector sent to instance

所以如果修飾代理屬性, 還是用weak把, 比較安全!

我想如果讀到這裏你應該對代理不陌生了吧, 也不暈了吧.






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