前言
關(guān)于類別,網(wǎng)上有大量優(yōu)秀的資料可以學(xué)習(xí)爸黄。但苦于自己這豆腐做的腦袋滞伟,每次研究完之后,過一陣子就忘記了炕贵。所以梆奈,這次打算一邊學(xué)習(xí),一邊整理成筆記称开,供自己后面溫習(xí)亩钟。(我這寫作的目的雖然自私,但也同樣愿意將學(xué)習(xí)筆記分享給大家鳖轰,也希望朋友們能夠多提意見清酥,大家共同進(jìn)步,雖然我是一個(gè)小菜鳥蕴侣,但我也有成為大神的理想)
這次寫作的動機(jī)還有一個(gè)焰轻,就是我剛學(xué)習(xí)了利用關(guān)聯(lián)給現(xiàn)有類擴(kuò)展屬性,并做了筆記(大部分筆記是借鑒前輩的昆雀,我覺得前輩寫的特別好辱志,在此,向這些大神前輩致謝)狞膘。類別和關(guān)聯(lián)就像兩兄弟揩懒,記錄了一個(gè)怎么都感覺不舒服(小小的強(qiáng)迫癥,還是可以接受的)挽封。
我們先來說說為什么會有類別這個(gè)東西
1已球,為系統(tǒng)框架擴(kuò)展方法,針對實(shí)際的運(yùn)用場景场仲,豐富系統(tǒng)框架的功能和悦。同時(shí)又不會破話系統(tǒng)框架的完整性。實(shí)際的運(yùn)用場景很多渠缕,我在這里不一一列舉鸽素,我們首先理解這個(gè)東西,然后再談使用亦鳞。系統(tǒng)框架沒有源碼馍忽,你就是想在類中增加方法也不可能(這不廢話嗎)棒坏。我們的開發(fā),無論何時(shí)都離不開系統(tǒng)提供的基礎(chǔ)框架遭笋,那么坝冕,基于系統(tǒng)框架擴(kuò)展的方法,就會擁有超強(qiáng)的生存能力瓦呼,也就是可以最大程度的復(fù)用代碼喂窟。當(dāng)遇到相同或者類似的場景時(shí),使用或者修改方法的實(shí)現(xiàn)即可央串。
2磨澡,從第一點(diǎn)就可以看出,我們在給系統(tǒng)或者自定義類擴(kuò)展方法時(shí)质和,并不受文件或者框架的限制稳摄,也就是說,我們可以靈活的在工程框架的任意位置為當(dāng)前的業(yè)務(wù)處理擴(kuò)展方法饲宿,這樣我們的擴(kuò)展可以無限接近我們的業(yè)務(wù)層厦酬,不僅方便代碼理解和維護(hù),同時(shí)也可以讓我們更加優(yōu)雅的寫代碼瘫想,不至于寫著寫著就要跳到工程的別的地方去了仗阅。
基于1,2兩點(diǎn)国夜,我們可以對類別這個(gè)東西下一個(gè)基本的定義:
為工程中存在的類擴(kuò)展方法
什么霹菊?就這么簡單。是的支竹,其實(shí)這就是類別最重要也是最基本的功能:擴(kuò)展方法旋廷;
個(gè)人理解:結(jié)合基本定義,同時(shí)在實(shí)際場景中合理利用類別礼搁,可以讓你的代碼變得優(yōu)雅自如饶碘。
有好就有壞,沒有陰陽調(diào)和馒吴,這家伙還不寂寞死扎运。
局限性
1,只能添加方法饮戳,不能添加屬性豪治。
這都是廢話了,為什么只能擴(kuò)展方法呢扯罐?屬性什么不能被直接擴(kuò)展呢负拟。
目前以我查到的資料顯示:類別是在程序運(yùn)行期將擴(kuò)展的方法加入到類的方法列表中(methodLists),但此時(shí)歹河,程序已經(jīng)編譯完成掩浙,類的內(nèi)存結(jié)構(gòu)已經(jīng)確定(類的內(nèi)存結(jié)構(gòu)是由類的屬性列表ivarsLIsts決定的)花吟,此時(shí)如果往屬性列表中添加屬性,會破話類的內(nèi)存結(jié)構(gòu)厨姚,這對編譯型語言來說是災(zāi)難性的衅澈。所以此時(shí)不可以改變其內(nèi)存結(jié)構(gòu),也就沒有辦法為該類添加屬性谬墙。
那么Runtime如何可以動態(tài)添加屬性呢今布?它添加屬性放入方式叫做關(guān)聯(lián)。說白了拭抬,它并沒有真正的將屬性添加到類的屬性列表中险耀,只是在內(nèi)存索引數(shù)組中,找到未使用的內(nèi)存空間玖喘,創(chuàng)建關(guān)聯(lián)對象,然后利用關(guān)鍵詞標(biāo)記該關(guān)聯(lián)對象的內(nèi)存指針蘑志,這樣累奈,當(dāng)通過類來使用該關(guān)聯(lián)對象時(shí),就可以通過關(guān)鍵詞來獲取該關(guān)聯(lián)對象急但,并使用該內(nèi)存澎媒。
http://blog.ibireme.com/2016/01/16/spinlock_is_unsafe_in_ios/
extension看起來很像一個(gè)匿名的category,但是extension和有名字的category幾乎完全是兩個(gè)東西波桩。 extension在編譯期決議戒努,它就是類的一部分,在編譯期和頭文件里的@interface以及實(shí)現(xiàn)文件里的@implement一起形成一個(gè)完整的類镐躲,它伴隨類的產(chǎn)生而產(chǎn)生储玫,亦隨之一起消亡。extension一般用來隱藏類的私有信息萤皂,你必須有一個(gè)類的源碼才能為一個(gè)類添加extension撒穷,所以你無法為系統(tǒng)的類比如NSString添加extension。
但是category則完全不一樣裆熙,它是在運(yùn)行期決議的端礼。
就category和extension的區(qū)別來看,我們可以推導(dǎo)出一個(gè)明顯的事實(shí)入录,extension可以添加實(shí)例變量蛤奥,而category是無法添加實(shí)例變量的(因?yàn)樵谶\(yùn)行期,對象的內(nèi)存布局已經(jīng)確定僚稿,如果添加實(shí)例變量就會破壞類的內(nèi)部布局凡桥,這對編譯型語言來說是災(zāi)難性的)。