Category的底層分析

2021-10-22 22:19:53 字數 1878 閱讀 7235

簡介:

category是objective-c 2.0之後新增的語言特性,分類、類別其實都是指的category。category的主要作用是為已經存在的類新增方法。

objective-c 中的 category 就是對裝飾模式的一種具體實現。它的主要作用是在不改變原有類的前提下,動態地給這個類新增一些方法。

知識回顧:

上面截圖就是category的具體實現,我們知道oc的執行時,呼叫run、eat、test方法其實是在內部objc_msgsend(person,@selector(eat))方法,由之前的部落格知識,我們知道,物件方法都是存在類物件裡面,test和eat分類是自己生成了乙個派生類嗎?是這樣嗎?你可能有這樣的疑問,實際上不是這樣的,類只有乙個類物件,接下來我們就去看看這個問題。

我們利用終端把test、eat分類轉成底層的c++檔案,利用:xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc gdperson+test.m

我這裡只轉乙個檔案,另乙個檔案也是一樣,大家可以嘗試,其實分類的資訊都是會生成乙個叫做 _category_t的乙個結構體,裡面分別name(名字),cls,instance_methods(物件方法)、class_methods(類方法)、protocols(協議資訊)、properties(屬性)。其實它是由幾個分類,就會生成幾個_category_t,上面是2個就會生成2個_category_t,上面的第二張就是傳的值,可以看得很清楚,只有乙個test方法,如果你寫2個方法轉一下c++檔案,就會有2個,大家都可以自己嘗試。這裡也可以看出,編譯的時候並沒有生產什麼新的類!

這裡我們去看一下,原始碼的實現,由於原始碼的步驟比較多,無法全部列出來,我把原始碼找的順序發一下,然後列一下最終找到的結果和實現

那個上面圖中最後一步:realloc、memmove和memcpy是比較之前的版本,請看***的截圖,是最新的版本

然後我們找一下attachlists的方法具體實現

從這我們可以得出一些總結,

1.通過runtime載入某個分類的所有category資料

2.把所有的category的方法、屬性、協議資料合併到乙個大陣列中後面參與編譯的category資料會在陣列的前面

3.將合併後的分類資料(方法、屬性、協議等)插入到類原來的資料中

1.category編譯之後的的底層結構是struct category_t,裡面儲存著分類的物件方法、類方法、屬性、協議資訊

2.在程式執行的時候,runtime會將category的資料,合併到類資訊中(類物件、元類物件)

class extension是在編譯的時候它的資料就儲存在類資訊中,而category是在執行時,才將資料合併到類資訊中。

接下來部落格我會介紹ios類別(category關於load的底層知識)的其他底層知識.

Category的底層分析之load

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

Category的底層分析之initialize

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

Category底層學習

1 category載入過程本質 在編譯的時候,category會被編譯成叫做 category t的結構體,裡面儲存了屬性列表 協議列表 物件方法 類方法列表。在程式執行時,runtime會將category的資料合併到類物件和元類物件中。所以category的方法屬性資訊還是存在類物件中 只是它...