第七條 :在對象內(nèi)部盡量直接訪問實(shí)例變量
在對象之外訪問實(shí)例變量是,總是應(yīng)該通過屬性來做瑞妇,那么在對象內(nèi)部訪問實(shí)例變量時(shí)又該如何呢玛荞?
除了幾種特殊情況外,在對象內(nèi)部讀取實(shí)例變量的時(shí)候采用直接訪問的形式州刽,而在設(shè)置實(shí)例變量的時(shí)候通過屬性來做空执。
使用點(diǎn)語法與直接訪問實(shí)例變量的幾個(gè)區(qū)別:
由于不經(jīng)過Objective-C的“方法派發(fā)”(method dispatch)步驟,所以直接訪問實(shí)例變量的速度當(dāng)然比較快穗椅。在這種情況下辨绊,編譯器所生成的代碼會直接訪問保存對象實(shí)例的那塊內(nèi)存。
直接訪問實(shí)例變量時(shí)匹表,不會調(diào)用其“設(shè)置方法”门坷,這就繞過了為設(shè)置相關(guān)屬性所定義的“內(nèi)存管理語義”。
比如說袍镀,ARC下直接訪問一個(gè)聲明為copy的屬性默蚌,那么并不會拷貝該屬性,只會保留新值并釋放舊值苇羡。
如果直接訪問實(shí)例變量绸吸,那么不會觸發(fā)“鍵值觀察”(key-Value Observing,KVO)通知。這樣做是否會產(chǎn)生問題锦茁,還取決于具體的對象行為攘轩。
通過屬性來訪問有助于排查與之相關(guān)的錯(cuò)誤,因?yàn)榭梢越o“獲取方法”和/或“設(shè)置方法”中新增“斷點(diǎn)”(breakpoint)蜻势,監(jiān)控該屬性的調(diào)用者及其訪問時(shí)機(jī)撑刺。
有一種合理的折中方案,就是:在寫入實(shí)例變量時(shí)握玛,通過其“設(shè)置方法”來做够傍,而在讀取該實(shí)例變量時(shí),則直接訪問挠铲。此辦法既能提高讀取操作的速度冕屯,又能控制對屬性的寫入操作。之所以要通過“設(shè)置方法”來寫入實(shí)例變量拂苹,其首要原因在于安聘,這樣能夠確保相關(guān)屬性的“內(nèi)存管理語義”得以貫徹。
但是選用這種做法需要注意幾個(gè)問題:
第一個(gè)問題:在初始化方法中應(yīng)該如何設(shè)置屬性值瓢棒。這種情況下總是應(yīng)該直接訪問實(shí)例變量浴韭,因?yàn)樽宇惪赡軙案矊憽保╫verride)設(shè)置方法。
另一個(gè)要注意的問題是:“惰性初始化”(lay initialization)脯宿。在這種情況下念颈,必須通過“獲取方法”來訪問屬性,否則连霉,實(shí)例變量就永遠(yuǎn)不會初始化榴芳。
若沒有調(diào)用“獲取方法”就直接訪問實(shí)例變量,則會看到尚未設(shè)置好的屬性跺撼,所以說窟感,如果使用了“懶加載”技術(shù),那么必須通過存取方法來訪問屬性歉井。
要點(diǎn):
1.在對象內(nèi)部讀取數(shù)據(jù)時(shí)柿祈,應(yīng)該通過實(shí)例變量來讀,而寫入數(shù)據(jù)時(shí)哩至,則應(yīng)通過屬性來寫
2.在初始化方法及delloc方法中躏嚎,總是應(yīng)該直接通過實(shí)例變量來讀寫數(shù)據(jù)
3.有時(shí)會使用懶加載初始化技術(shù)配置某份數(shù)據(jù),這種情況下憨募,需要通過屬性來讀取數(shù)據(jù)