第2章 對象、消息、運(yùn)行期

第6條:理解屬性這一概念

可以使用@property語法來定義對象中所封裝的數(shù)據(jù)。

通過“特質(zhì)”來指定存取數(shù)據(jù)所需的正確語句。

在設(shè)置屬性所對應(yīng)的實(shí)例變量時(shí),一定要遵從該屬性所聲明的語義。

開發(fā)iOS程序是應(yīng)盡量使用nonatomic屬性,因?yàn)閍tomic屬性會(huì)嚴(yán)重影響性能。

@synthesize語法指定實(shí)例變量的名字。@synthesize firstName = _myFirstName;

@dynamic:它會(huì)告訴編譯器:不要自動(dòng)創(chuàng)建實(shí)例變量和存儲(chǔ)方法。

assign:簡單賦值操作。

strong:設(shè)置方法先保留新值,并釋放舊值,然后將新值設(shè)置上去。

weak:設(shè)置方法既不保留新值,也不釋放舊值。摧毀時(shí),屬性值清空(nil out);

unsafa_unretained:與assign相同,但摧毀時(shí),屬性值不會(huì)自動(dòng)清空,與weak有區(qū)別。

copy:設(shè)置方法不保留新值,而是將其拷貝。

第7條:在對象內(nèi)部盡量直接訪問實(shí)例變量

由于不經(jīng)過OC的“方法派發(fā)”步驟,所以直接訪問實(shí)例變量的速度較快。在這種情況下,編譯器所生成的代碼會(huì)直接訪問保存對象實(shí)例變量的那塊內(nèi)存。

直接訪問實(shí)例變量時(shí),不會(huì)調(diào)用其“設(shè)置方法”,這就繞過了為其屬性所定義的“內(nèi)存管理語義”。比方說,如果在ARC下直接訪問一個(gè)聲明為copy的屬性,那么并不會(huì)拷貝該屬性,只會(huì)保留新值,并釋放舊值。

如果直接訪問實(shí)例變量,那么不會(huì)觸發(fā)“鍵值觀測”(KVO)通知。這樣做是否會(huì)產(chǎn)生問題,還取決于具體的對象行為。

通過屬性來訪問有助于排查與之相關(guān)的錯(cuò)誤。

在對象內(nèi)部讀取數(shù)據(jù)時(shí),應(yīng)該直接通過實(shí)例變量來讀,而在寫入數(shù)據(jù)時(shí),則應(yīng)通過屬性來寫。

在初始化方法及dealloc方法中,總是應(yīng)該直接通過實(shí)例變量來讀寫數(shù)據(jù)。

有時(shí)會(huì)使用懶加載,這種情況下,需要通過屬性來讀取數(shù)據(jù)。

第8條:理解“對象等同性”這一概念

若想檢測對象的等同性,請?zhí)峁癷sEqual:”與hash方法。

相同的對象必須具有相同的哈希碼,但是兩個(gè)哈希碼相同的對象卻未必相同。

不要盲目地逐個(gè)檢測每條屬性,而是應(yīng)該依照具體需求來制定檢測方案。

編寫hash方法時(shí),應(yīng)該使用計(jì)算速度快而且哈希碼碰撞幾率低的算法。

第9條:以“類族模式”隱藏實(shí)現(xiàn)細(xì)節(jié)

類族模式可以把實(shí)現(xiàn)細(xì)節(jié)隱藏在一套簡單的公共接口后面。

系統(tǒng)框架中經(jīng)常使用類族。

從類族的公共抽象基類中繼承子類時(shí)要小心,若有開發(fā)文檔,首先閱讀。

第10條:在既有類中使用關(guān)聯(lián)對象存放自定義數(shù)據(jù)

可以通過“關(guān)聯(lián)對象”機(jī)制來把兩個(gè)對象連起來。

定義關(guān)聯(lián)對象時(shí)可指定內(nèi)存管理語義,用以模仿定義屬性時(shí)所采用的“擁有關(guān)系”與“非擁有關(guān)系”。

只有在其他做法不可行時(shí)才應(yīng)選擇關(guān)聯(lián)對象,因?yàn)檫@種做法通常會(huì)引入難以查找的bug。

第11條:理解objc_msgSend的作用

消息由接受者、選擇子及參數(shù)構(gòu)成。給某對象“發(fā)送消息(invoke a message)”也就是相當(dāng)于在該對象上“調(diào)用方法”(call a method)。

發(fā)給某對象的全部消息都要由“動(dòng)態(tài)消息派發(fā)系統(tǒng)”(dynamic message dispatch sysytem)來處理,該系統(tǒng)會(huì)查出對應(yīng)的方法,并執(zhí)行其代碼。

第12條:理解消息轉(zhuǎn)發(fā)機(jī)制

若對象無法響應(yīng)某個(gè)選擇子,則進(jìn)入消息轉(zhuǎn)發(fā)流程。

通過運(yùn)行期的動(dòng)態(tài)方法解析功能,我們可以在需要用到某個(gè)方法時(shí)再將其加入類中。

對象可以把其無法解讀的某些選擇子轉(zhuǎn)交給其他對象處理。

經(jīng)過上述兩步之后,如果還是沒有辦法處理選擇子,那就啟動(dòng)完整的消息轉(zhuǎn)發(fā)機(jī)制。

第13條:用“方法調(diào)配技術(shù)”調(diào)試“黑盒方法”

在運(yùn)行期,可以向類中新增或替換選擇子所對應(yīng)的方法實(shí)現(xiàn)。

使用另一份實(shí)現(xiàn)來替換原有的方法實(shí)現(xiàn),這道工序叫做“方法調(diào)配”,開發(fā)者常用此技術(shù)向原有實(shí)現(xiàn)中添加新功能。

一般來說,只有調(diào)試程序的時(shí)候才需要在運(yùn)行期修改方法實(shí)現(xiàn),這種方法不易濫用。

第14條:理解“類對象”的用意

每個(gè)實(shí)例都有一個(gè)指向 Class 對象的指針,用以表明其類型,而這些 Class 對象則構(gòu)成了類的繼承體系。

如果對象類型無法再編譯期確定,那么就應(yīng)該使用類型信息查詢(is kind of class)來探知。

盡量使用類型信息查詢方法來確定對象類型,而不要直接比較類對象,因?yàn)槟承ο罂赡軐?shí)現(xiàn)了消息轉(zhuǎn)發(fā)功能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容