Category載入流程
當我們啟動App時,會對Objc類進行初始化,這裡我們探討的是關於Category的載入流程,如上圖所示.
在load_categories_nolock方法中通過_getObjc2CategoryList
獲取分類列表,在attachCategories()方法中,首先會初始化三個陣列,分別是method_list_t
,property_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_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
,
可以看出,當我們在分類中新增屬性時,得自己實現對應的setter、getter方法,通過關聯物件objc_setAssociatedObject實現屬性的儲存。