第七條 :在對(duì)象內(nèi)部盡量直接訪問實(shí)例變量
在對(duì)象之外訪問實(shí)例變量是,總是應(yīng)該通過屬性來做,那么在對(duì)象內(nèi)部訪問實(shí)例變量時(shí)又該如何呢?
除了幾種特殊情況外,在對(duì)象內(nèi)部讀取實(shí)例變量的時(shí)候采用直接訪問的形式,而在設(shè)置實(shí)例變量的時(shí)候通過屬性來做。
使用點(diǎn)語法與直接訪問實(shí)例變量的幾個(gè)區(qū)別:
由于不經(jīng)過Objective-C的“方法派發(fā)”(method dispatch)步驟,所以直接訪問實(shí)例變量的速度當(dāng)然比較快。在這種情況下,編譯器所生成的代碼會(huì)直接訪問保存對(duì)象實(shí)例的那塊內(nèi)存。
直接訪問實(shí)例變量時(shí),不會(huì)調(diào)用其“設(shè)置方法”,這就繞過了為設(shè)置相關(guān)屬性所定義的“內(nèi)存管理語義”。
比如說,ARC下直接訪問一個(gè)聲明為copy的屬性,那么并不會(huì)拷貝該屬性,只會(huì)保留新值并釋放舊值。
如果直接訪問實(shí)例變量,那么不會(huì)觸發(fā)“鍵值觀察”(key-Value Observing,KVO)通知。這樣做是否會(huì)產(chǎn)生問題,還取決于具體的對(duì)象行為。
通過屬性來訪問有助于排查與之相關(guān)的錯(cuò)誤,因?yàn)榭梢越o“獲取方法”和/或“設(shè)置方法”中新增“斷點(diǎn)”(breakpoint),監(jiān)控該屬性的調(diào)用者及其訪問時(shí)機(jī)。
有一種合理的折中方案,就是:在寫入實(shí)例變量時(shí),通過其“設(shè)置方法”來做,而在讀取該實(shí)例變量時(shí),則直接訪問。此辦法既能提高讀取操作的速度,又能控制對(duì)屬性的寫入操作。之所以要通過“設(shè)置方法”來寫入實(shí)例變量,其首要原因在于,這樣能夠確保相關(guān)屬性的“內(nèi)存管理語義”得以貫徹。
但是選用這種做法需要注意幾個(gè)問題:
第一個(gè)問題:在初始化方法中應(yīng)該如何設(shè)置屬性值。這種情況下總是應(yīng)該直接訪問實(shí)例變量,因?yàn)樽宇惪赡軙?huì)“覆寫”(override)設(shè)置方法。
另一個(gè)要注意的問題是:“惰性初始化”(lay initialization)。在這種情況下,必須通過“獲取方法”來訪問屬性,否則,實(shí)例變量就永遠(yuǎn)不會(huì)初始化。
若沒有調(diào)用“獲取方法”就直接訪問實(shí)例變量,則會(huì)看到尚未設(shè)置好的屬性,所以說,如果使用了“懶加載”技術(shù),那么必須通過存取方法來訪問屬性。
要點(diǎn):
1.在對(duì)象內(nèi)部讀取數(shù)據(jù)時(shí),應(yīng)該通過實(shí)例變量來讀,而寫入數(shù)據(jù)時(shí),則應(yīng)通過屬性來寫
2.在初始化方法及delloc方法中,總是應(yīng)該直接通過實(shí)例變量來讀寫數(shù)據(jù)
3.有時(shí)會(huì)使用懶加載初始化技術(shù)配置某份數(shù)據(jù),這種情況下,需要通過屬性來讀取數(shù)據(jù)