iOS所有對象的最終的父類都是NSObject,NSProxy不是NSObject的子類。NSObject有一個數據結構,就是isa指針。
元類(metaclass):在oc中,每一個類實際上也是一個對象。也有一個isa指針。因為類也是一個對象,所以也必須是另外一個類的實例,這個類就是元類(metaclass),即元類的對象就是這個類,元類保存了類方法的列表。
元類的注意點:
1.所有的元類的isa指針都會指向一個根元類。根元類的isa指針會指向他自己。
2.根metaclass(元類)中的superClass指針指向根類,因為根metaclass(元類)是通過繼承根類產生的。
?Class是一個指向objc_class(類)結構體的指針,而id是一個指向objc_object(對象)結構體的指針。
objc_object(對象)中isa指針指向的類結構稱為objc_class(該對象的類),objc_class存放著普通成員變量與對象方法 (“-”開頭的方法)。
objc_class(類)中isa指針指向的類結構稱為metaclass(該類的元類),其中存放著static類型的成員變量與static類型的方法 (“+”開頭的方法)。
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指針指向的objc_class(類)的methodLists中查找該方法,如果找不到則會通過objc_class(類)的super_class指針找到其父類,然后從其methodLists中查找該方法,如果仍然找不到,則繼續通過 super_class向上一級父類結構體中查找,直至根class;
類方法的調用:
當我們調用某個類方法時,它首先通過自己的isa指針指向的objc_class中的isa指針找到元類,并從其methodLists中查找該類方法,如果找不到則會通過元類)的super_class指針找到父類的元類結構體,然后從methodLists中查找該方法,如果仍然找不到,則繼續通過super_class向上一級父類結構體中查 找,直至根元類;
方法的cache:
運行的時候編譯器會將代碼轉化為objc_msgSend(obj, @selector (makeText)),在objc_msgSend函數中首先通過obj(對象)的isa指針找到obj(對象)對應的class(類)。在class(類)中先去cache中通過SEL(方法的編號)查找對應method(方法),若cache中未找到,再去methodLists中查找,若methodists中未找到,則去superClass中查找,若能找到,則將method(方法)加入到cache中,以方便下次查找,并通過method(方法)中的函數指針跳轉到對應的函數中去執行。
引用:OC-底層實現isa指針
? ??????????ios中isa指針