@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(方法)中的函數指針跳轉到對應的函數中去執行。