iOS Class中的實例、類、元類、isa

實例對象(id)

實例對象是咱們對類對象alloc或者new操做時所建立的,在這個過程當中會拷貝實例所屬類的成員變量,但並不拷貝類定義的方法。緩存

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;
複製代碼

objc_object這個結構體只有一個isa變量,指向實例對象所屬的類。任何帶有以指針開始並指向類結構的結構均可以被視做objc_object, 對象最重要的特色是能夠給其發送消息。bash

類(Class)

typedef struct objc_class *Class;
複製代碼

因而可知 ,Class是指向C的結構體objc_class的指針,咱們再看一下objc_class的定義函數

元類(objc_class)

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif
複製代碼
  • isa指針是和Class同類型的objc_class結構指針,類對象的指針指向其所屬的類,即元類。元類中存儲着類對象的類方法,當訪問某個類的類方法時會經過該isa指針從元類中尋找方法對應的函數指針。
  • super_class爲該類所繼承的父類對象,若是該類已是最頂層的根類(如NSObject或NSProxy), 則 super_class爲NULL。
  • ivars是一個指向objc_ivar_list類型的指針,用來存儲每個實例變量的地址。
  • info爲運行期使用的一些位標識,好比:CLS_CLASS (0x1L)表示該類爲普通類, CLS_META (0x2L)則表示該類爲元類。
  • methodLists用來存放方法列表,根據info中的標識信息,當該類爲普通類時,存儲的方法爲實例方法;若是是元類則存儲的類方法。
  • cache用於緩存最近使用的方法。系統在調用方法時會先去cache中查找,在沒有查找到時纔會去methodLists中遍歷獲取須要的方法。

isa

是一個Class 類型的指針,每一個實例對象有個isa的指針,他指向對象的類,而Class裏也有個isa的指針, 指向meteClass(元類)spa

實例、類、元類、isa 關係圖:

因而可知,在給實例對象或類對象發送消息時,尋找方法列表的規則爲:指針

  • 當發送消息給實例對象時,消息是在尋找這個對象的類的方法列表(實例方法)
  • 當發送消息給類對象時,消息是在尋找這個類的元類的方法列表(類方法)

全部元類都有一個根元類,好比全部NSObject的子類的元類都會以NSObject的元類做爲他們的類。全部的元類使用根元類做爲他們的類,根元類的元類則就是它本身,也就是說根元類的isa指針指向他本身。code

總結:

object_getClass(實例對象) == [實例對象 class]
[類對象 class] == 類對象
object_getClass(類對象) == 類對象的isa == 元類
object_getClass(類對象) != [類對象 class]
複製代碼
相關文章
相關標籤/搜索