ios OC swift run-time isa 指針

@interface Object { 
    Class isa; 
} 

Class

#if !OBJC_TYPES_DEFINED
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

/// 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;
#endif

/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;   //isa指針,指向metaclass(該類的元類)
 
#if !__OBJC2__
 
    Class super_class   //指向objc_class(該類)的super_class(父類)
 
    const char *name    //objc_class(該類)的類名
 
    long version        //objc_class(該類)的版本信息,初始化爲0,可以通過runtime函數class_setVersion和class_getVersion進行修改和讀取
 
    long info           //一些標識信息,如CLS_CLASS表示objc_class(該類)爲普通類。ClS_CLASS表示objc_class(該類)爲metaclass(元類)
 
    long instance_size  //objc_class(該類)的實例變量的大小
 
    struct objc_ivar_list *ivars    //用於存儲每個成員變量的地址
 
    struct objc_method_list **methodLists   //方法列表,與info標識關聯
 
    struct objc_cache *cache        //指向最近使用的方法的指針,用於提升效率
 
    struct objc_protocol_list *protocols    //存儲objc_class(該類)的一些協議
#endif
 
} OBJC2_UNAVAILABLE;

每個對象都有一個 isa

isa 通俗一點理解就是。我們可以理解爲是一個表

這個表裏面存儲了所有關於這個對象或類的信息

從上面可以看出來 屬性、方法、協議、super_class 都可以在裏面獲取到

同樣但我們執行方法、獲取屬性等都要從 isa Class 中獲取

證明對象的信息存儲在 isa 中

MM * m = [[MM alloc] init];
        
object_setClass(m, objc_getClass("KK"));
        
 [m setValue:@(10) forKey:@"i"];

NSLog(@"%@", m);


==== console ==

KK -> description:10

證明 metaclass(元類)中isa指針則指向自身

bool isRootClass() {
       return superclass == nil;
}

/// 根 metaClass 的 isa 指向它自身
bool isRootMetaclass() {
      return ISA() == (Class)this;
}

bool isMetaClass() {
      return info & CLS_META;
}

證明 objec_class(類)中isa指針指向的類結構稱爲metaclass(該類的元類

/***********************************************************************
* objc_getMetaClass.  Return the id of the meta class the named class.
* Warning: doesn't work if aClassName is the name of a posed-for class's isa!
**********************************************************************/
Class objc_getMetaClass(const char *aClassName)
{
    Class cls;

    if (!aClassName) return Nil;

    cls = objc_getClass (aClassName);
    if (!cls)
    {
        _objc_inform ("class `%s' not linked into application", aClassName);
        return Nil;
    }

    return cls->ISA();
}

以下內容爲摘抄內容:

內容講解的非常詳細,並且很容易理解

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
/// A pointer to an instance of a class.
typedef struct objc_object *id;
  • Class是一個指向objc_class(類)結構體的指針,而id是一個指向objc_object(對象)結構體的指針。
  • objec_object(對象)中isa指針指向的類結構稱爲objec_class(該對象的類),其中存放着普通成員變量與對象方法 (“-”開頭的方法)。
  • objec_class(類)中isa指針指向的類結構稱爲metaclass(該類的元類),其中存放着static類型的成員變量與static類型的方法 (“+”開頭的方法)。可以查看上面的證明方法
  • objec_object(對象)結構體中只有isa一個成員屬性,指向objec_class(該對象的類)。
  • objec_class(類)比objec_object(對象)的結構體中多了很多成員,上面就是介紹各個成員的作用。

值得注意的是:

  • 所有的metaclass(元類)中isa指針都是指向根metaclass(元類),而根metaclass(元類)中isa指針則指向自身。可以查看上面的證明方法
  • 根metaclass(元類)中的superClass指針指向根類,因爲根metaclass(元類)是通過繼承根類產生的。

作用:

  • 當我們調用某個對象的對象方法時,它會首先在自身isa指針指向的objc_class(類)的methodLists中查找該方法,如果找不到則會通過objc_class(類)的super_class指針找到其父類,然後從其methodLists中查找該方法,如果仍然找不到,則繼續通過 super_class向上一級父類結構體中查找,直至根class;
  • 當我們調用某個類方法時,它會首先通過自己的isa指針找到metaclass(元類),並從其methodLists中查找該類方法,如果找不到則會通過metaclass(元類)的super_class指針找到父類的metaclass(元類)結構體,然後從methodLists中查找該方法,如果仍然找不到,則繼續通過super_class向上一級父類結構體中查 找,直至根metaclass(元類);
  • 這裏有個細節就是要說運行的時候編譯器會將代碼轉化爲objc_msgSend(obj, @selector (makeText)),在objc_msgSend函數中首先通過obj(對象)的isa指針找到obj(對象)對應的class(類)。在class(類)中先去cache中通過SEL(方法的編號)查找對應method(方法),若cache中未找到,再去methodLists中查找,若methodists中未找到,則去superClass中查找,若能找到,則將method(方法)加入到cache中,以方便下次查找,並通過method(方法)中的函數指針跳轉到對應的函數中去執行。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章