Category底層學習

2021-10-23 11:47:52 字數 1749 閱讀 3724

1、category載入過程本質

在編譯的時候,category會被編譯成叫做_category_t的結構體,裡面儲存了屬性列表、協議列表、物件方法、類方法列表。在程式執行時,runtime會將category的資料合併到類物件和元類物件中。

所以category的方法屬性資訊還是存在類物件中;只是它們是在執行時加入類的;方法的呼叫還是會通過isa指標去class物件、mate_class物件中查詢。

2、多個category實現同乙個方法,會呼叫哪乙個category的方法

會呼叫最後編譯的category的方法;因為在多個category資訊合併到類或者元類中,是以倒序方式合併進

去的,當呼叫方法的時候 就會首先找到最後編譯的category方法。

3、 category和類擴充套件class extension的區別

class extension的內容是編譯時就決議的,它的資料就包含在類資訊中;

category在程式執行時,runtime會將category的資料合併到類物件和元類物件中;

4、category裡面有load方法嗎? +load方法什麼時候呼叫? load方法可以繼承嗎?

load方法的呼叫是通過函式指標直接拿到方法進行直接呼叫的,並不是通過objc_msgsend()呼叫

肯定是有load方法的;

load方法會在runtime 載入 類、分類的時候呼叫 ;而且只執行一次

load方法的呼叫順序不受分類load方法的影響,在低層call_class_loads方法中始終最先呼叫類的load方法,分類的load方法是先編譯先呼叫

load方法可以被繼承,但是不會主動呼叫,load方法一般是系統呼叫

load用途:載入的時候想做什麼事情寫在load方法裡面

4、initialize方法什麼時候呼叫

initialize會在類第一次接收到訊息(第一次初始化)的時候呼叫;主要是因為objc_msgsend()內部原始碼實現會去檢查是否初始化,沒有就呼叫initalize,而且是先呼叫父類的initalize,再子類。

呼叫順序:先呼叫父類在呼叫子類的initialize

initialize用途:第一次使用該類想做什麼事情寫在裡面

5、load和initialize的區別,他們在category中的呼叫順序有什麼不一樣,以及出現繼承他們的呼叫過程

呼叫時機不一樣:load是runtime載入類、分類的時候呼叫;initialize是第一次收到訊息的時候呼叫,只執行一次(但是它子類沒有實現會被多次呼叫)

load是先編譯先呼叫,先呼叫父類再子類,category也是先編譯先呼叫;initialize先初始化父類再初始化子類

6、 分類裡面可以新增成員變數嗎?怎麼實現新增屬性?

category的資料結構不能存放成員變數

可以新增屬性,但只產生了set、get方法的宣告,並沒有生成成員變數和set、get方法的實現; 

7、關聯物件 - 分類新增屬性

底層實現實際就是字典裡面再套了一層字典。

Category的底層分析

簡介 category是objective c 2.0之後新增的語言特性,分類 類別其實都是指的category。category的主要作用是為已經存在的類新增方法。objective c 中的 category 就是對裝飾模式的一種具體實現。它的主要作用是在不改變原有類的前提下,動態地給這個類新增...

Category的底層分析之load

今天我們就圍繞乙個面試題來從原始碼的角度分析答案!一 category中有load方法嗎?load方法是什麼時候呼叫的?load方法能繼承嗎?如果分類又存在繼承是如何載入load順序的呢?首先我們先看下下面的 我們先看 執行結果,再從原始碼上分析!gdperson.m檔案裡面 void load g...

Category的底層分析之initialize

這篇部落格我們將圍繞這幾個問題來 initialize.首先看我的截圖,我們先看一下initialize會不會像load一樣,runtime載入類 分類的時候就會呼叫.還是一樣,我建立gdperson類和test1 test2分類,裡面分別呼叫了initialize方法,如下 initialize方...