【iOS】分類 擴展 關聯對象 核心解讀

分類 擴展 關聯對象

思路

  1. 做了哪些事情?
  2. 特點
  3. 侷限性
  4. 源碼分析

1. 概述:

不知道源碼的情況下爲類添加方法,可在現有的類的基礎上添加新的方法。

2. 主要作用

  1. 分解體積大的類文件
  2. 聲明私有方法
  3. 把Framework的私有方法公開
  4. 模擬多繼承

3. 底層實現

struct category_t {
    const char *name;
    classref_t cls;
    struct method_list_t *instanceMethods;
    struct method_list_t *classMethods;
    struct protocol_list_t *protocols;
    struct property_list_t *instanceProperties;
    // Fields below this point are not always present on disk.
    struct property_list_t *_classProperties;

    method_list_t *methodsForMeta(bool isMeta) {
        if (isMeta) return classMethods;
        else return instanceMethods;
    }

    property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};

從category結構可以看出:

  1. 可以添加實例方法,類方法,協議,添加實例屬性,類屬性(但這裏的屬性不會自動生成實例變量和對應的get,set方法,需要通過關聯對象來實現)
  2. 不可以添加實例變量

加載調用棧

_objc_init ->map_2_images 鏡像->map_images_nlock -> 
_read_images->remethodizeClass

把category的實例方法、協議以及屬性添加到類上
把category的類方法和協議添加到類的metaclass上

說明:
在remethodizeClass內部核心方法是:attachCategories
attachLists: 將含有mcount個元素 的mlists拼接到rw的methods上

特點:

運行時決議
可爲系統類添加分類

多總結 多看源碼

關聯對象

提供了以下API:

// 1. 添加關聯對象
void objc_setAssociatedObject(id object, const  void* key, id value, objc_AssociationPolicy policy)

// 2. 獲得關聯對象
id objc_getAssociatedObject(id object, const void* key)

// 3. 移除所有的關聯對象
void objc_removeAssociatedObjects(id object)

其中policy屬性,是一個枚舉值,常見修飾詞。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LoD0y0l3-1578018300136)(media/15779461828350/15779542321735.jpg)]

關聯對象底層實現依賴四個核心對象:
AssocationManager
AssocationHashMap
objectAssociationMap
ObjectAssociation
AssocationManager裏面存儲着某個對象的關聯對象Map表,即ObjectAssociationMap,這個表存儲了多個關聯對象,objectAssociationMap就是我們添加的關聯對象.

實現原理

關聯本質
AssociationManager管理並在AssociationHashMap存儲
所有對象的關聯內容都在統一全局容器中。

擴展

定義:
Extension是Category的一個特例,類擴展與分類只少了分類的名稱,所以又稱之爲匿名分類。
作用 :

  1. 聲明私有屬性
  2. 聲明私有方法
  3. 聲明私有成員變量

特點:
編譯時決議

只以聲明的形式存在,多數情況下寄生於宿主類中,不能爲系統類添加擴展

特點:

  1. 編譯時決議
  2. 不能爲系統類添加擴展

因爲運行期,對象的內部佈局已經確定,如果添加實例變量會破壞類的內部佈局,這對編譯性語言是災難性的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章