OC對象的三種分類(二)


問題:緩存

  1. 對象的isa指針指向哪裏
  • 實例對象的isa指向類對象
  • 類對象的isa指向元類對象
  • 元類對象的isa指向基類的元類對象
  1. oc對象的信息存儲在哪裏?
  • 對象方法、屬性、成員變量、協議存儲在class對象中
  • 類方法存儲在元類對象中
  • 成員變量的值存儲在實例對象中

object-c中的對象主要分爲3種:

  • instance對象(實例對象)
  • class對象(類對象)
  • meta-class對象(元類對象)

instance對象

  • instance對象就是經過類alloc出來的對象,每次調用alloc都會產生新的instance對象
  • 內存中存儲着:
  • isa指針
  • 其餘成員變量

class對象

  • 每一個類對象在內存中有且只有一個class對象
  • 內存中存儲着:

  • isa指針
  • superclass指針
  • 類的屬性信息(@property)、類的對象方法信息(instance > * method)
  • 類的協議信息(protocol)、類的成員變量信息(ivar)
  • 其餘成員變量

meta-class對象

  • 即類對象的isa所指向的對象,每一個類在內存中有且只有一個meta-class對象
  • meta-class對象和class對象的內存結構是同樣的,可是用途不同
  • 經過 object_getclass可獲取到元類對象
  • 內存中存儲着:

  • isa指針
  • superclass指針
  • 類的屬性信息(@property)、類的對象方法信息(instance > * method)
  • 類的協議信息(protocol)、類的成員變量信息(ivar)
  • 其餘成員變量

三種對象的isa和superclass指針之間的關係

  • isa指針

  • class對象的superclass指針

  • meta-class對象的superclass指針

  • 總結

class結構

從底層來看,class和meta-class都是objc_class結構markdown

struct objc_class  {
    Class ISA;
    Class superclass;
    cache_t cache;             // 方法緩存
    class_data_bits_t bits;    // 類的具體信息,想要&FAST_DATA_MASK才能獲取到正確的地址
    ...
};
複製代碼

class_data_bits_t結構大致:ui

struct class_data_bits_t {
    class_rw_t* data; //存儲類的信息
    ...
}
複製代碼

class_rw_t大致結構:atom

struct class_rw_t { 
    uint32_t flags;
    uint16_t witness;
    explicit_atomic<uintptr_t> ro_or_rw_ext;
    Class firstSubclass;
    Class nextSiblingClass;
    using ro_or_rw_ext_t = objc::PointerUnion<const class_ro_t *, class_rw_ext_t *>;
    const ro_or_rw_ext_t get_ro_or_rwe();
    const class_ro_t *ro();
    const method_array_t methods();         //方法列表
    const property_array_t properties();    //屬性列表
    const protocol_array_t protocols();     //協議列表
    ...
};
複製代碼

其中ro結構體爲:spa

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;			 //實例建立出來的佔用的空間大小
#ifdef __LP64__
    uint32_t reserved;
#endif
    const uint8_t * ivarLayout;
    const char * name;                //類名
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;
    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;
    ...
};
複製代碼

小細節:define ISA_MASK 0x0000000ffffffff8ULL能夠發現isa指向的類或者元類對象的地址,最後三位都是0。3d

相關文章
相關標籤/搜索