Category-載入流程、底層結構分析

一隻煮熟了的鴨子發表於2020-04-06

Category-載入流程、底層結構分析

Category載入流程

Category-載入流程、底層結構分析

當我們啟動App時,會對Objc類進行初始化,這裡我們探討的是關於Category的載入流程,如上圖所示.

在load_categories_nolock方法中通過_getObjc2CategoryList獲取分類列表,在attachCategories()方法中,首先會初始化三個陣列,分別是method_list_tproperty_list_t,protocol_list_t,並申明陣列的容量大小ATTACH_BUFSIZ = 64, 在官方註釋中,解釋到只有少數的幾個類擁有超過64個類別

  * Only a few classes have more than 64 categories during launch.
  * This uses a little stack, and avoids malloc.
複製程式碼

然後遍歷分類列表,將分類的資訊附加到對應class中,按照編譯順序,最後編譯的方法將會放在前面,同時將方法新增到類後,更新方法快取列表。

Category-載入流程、底層結構分析

Category底層結構分析

Category-載入流程、底層結構分析

如上圖,Category是個category_t結構體,其內包含了類名、關聯類、例項方法列表、類方法列表、協議列表、例項屬性列表、類屬性列表。

Category新增屬性

通過category_t可知,我們可以通過分類新增方法、屬性以及協議,那麼如何通過分類新增屬性呢?property = _ivar + setter + getter,通常我們在類中宣告一個屬性時,編譯器會預設的幫我們實現setter、getter方法,那麼我們在分類中宣告一個屬性時,編譯器會幫我們預設實現嘛?

分類新增屬性,未實現setter、getter方法,通過lldb除錯列印此時person類中class_rw_t內的資訊,可以看到宣告的nickName屬性,但是methods列表內只有init方法,編譯時編譯器已經給出警告,Property 'nickName' requires method 'nickName' to be defined - use @dynamic or provide a method implementation in this category,

Category-載入流程、底層結構分析
Category-載入流程、底層結構分析

可以看出,當我們在分類中新增屬性時,得自己實現對應的setter、getter方法,通過關聯物件objc_setAssociatedObject實現屬性的儲存。

相關文章