標籤:ios objective-c runtime objc_class class
Objective-C objc_class 介紹NSObject
Objective-C 中 NSObject是大多數類的根類。
@interface NSObject <NSObject> { Class isa OBJC_ISA_AVAILABILITY;}
它有一個isa屬性,類型是Class.
蘋果已經將 ObjC runtime 代碼開源了,我們下載下,看看Class到底是什麼http://opensource.apple.com/tarballs/objc4/objc4-493.9.tar.gz
objc_class
我們可以在<objc.h>檔案裡看到Class的定義
typedef struct objc_class *Class;typedef struct objc_object { Class isa;} *id;
Class 是一個 objc_class 結構類型的指標, id是一個 objc_object 結構類型的指標.
objc_class的定義可以在<runtime.h>裡找到
struct objc_class { Class isa; Class super_class; const char *name; long version; long info; long instance_size; struct objc_ivar_list *ivars; struct objc_method_list **methodLists; struct objc_cache *cache; struct objc_protocol_list *protocols;} OBJC2_UNAVAILABLE;
接下來我們來看下每個屬性的意思
isa
是一個 Objective-C Class 類型的指標. 執行個體對象有個isa的屬性,指向Class, 而Class裡也有個isa的屬性, 指向meteClass. 這裡就有個點, 在Objective-C中任何的類定義都是對象.
super_class
指向該類的父類, 如果該類已經是最頂層的根類(如 NSObject 或 NSProxy),那麼 super_class 就為 NULL.
他們的關係呢,這裡有個圖http://www.sealiesoftware.com/blog/class%20diagram.pdf
name
我們先看下下面的代碼
id objc_getClass(const char *aClassName){ if (!aClassName) return Nil; // NO unconnected, YES class handler return look_up_class(aClassName, NO, YES);}PRIVATE_EXTERN id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler){ BOOL includeClassLoader = YES; // class loader cannot be skipped id result = nil; struct old_class query; query.name = aClassName; retry: if (!result && class_hash) { // Check ordinary classes mutex_lock (&classLock); result = (id)NXHashGet(class_hash, &query); mutex_unlock (&classLock); } if (!result && includeUnconnected && unconnected_class_hash) { // Check not-yet-connected classes mutex_lock(&classLock); result = (id)NXHashGet(unconnected_class_hash, &query); mutex_unlock(&classLock); } if (!result && includeClassLoader && _objc_classLoader) { // Try class loader callback if ((*_objc_classLoader)(aClassName)) { // Re-try lookup without class loader includeClassLoader = NO; goto retry; } } if (!result && includeClassHandler && objc_classHandler) { // Try class handler callback if ((*objc_classHandler)(aClassName)) { // Re-try lookup without class handler or class loader includeClassLoader = NO; includeClassHandler = NO; goto retry; } } return result;}struct old_class { struct old_class *isa; struct old_class *super_class; const char *name; long version; long info; long instance_size; struct old_ivar_list *ivars; struct old_method_list **methodLists; Cache cache; struct old_protocol_list *protocols; // CLS_EXT only const uint8_t *ivar_layout; struct old_class_ext *ext;};
objc_getClass從一個字串返回一個類,look_up_class,先建立一個old_class對象,name賦值為這個字串,如果找到了,就返回old_class.看下old_class的結構就能看出name這個屬性存的值就是類的名字(其實name不就是名字嘛)
version
類的版本資訊,預設為0
info
供運行期使用的一些位標識。
instance_size
該類的執行個體變數大小
ivars
struct objc_ivar_list { int ivar_count; /* variable length structure */ struct objc_ivar ivar_list[1];}
成員變數的數組
methodLists
方法定義的數組
struct objc_method_list { struct objc_method_list *obsolete; int method_count; /* variable length structure */ struct objc_method method_list[1];}
objc_cache
指向最近使用的方法.用於方法調用的最佳化.
struct objc_cache { unsigned int mask /* total = mask + 1 */; unsigned int occupied; Method buckets[1];};
protocols
協議的數組
struct objc_protocol_list { struct objc_protocol_list *next; long count; Protocol *list[1];};