Runtime是想要做好iOS開發(fā),或者說是真正的深刻的掌握OC這門語言所必需理解的東西。
什么是 Runtime
1.我們寫的代碼在程序運(yùn)行過程中都會(huì)被轉(zhuǎn)化成runtime的C代碼執(zhí)行,例如 ?[target doSomething] ?會(huì)被轉(zhuǎn)化成 ?objc_msgSend(target, @selector(doSomething));。
2.OC中一切都被設(shè)計(jì)成了對(duì)象,我們都知道一個(gè)類被初始化成一個(gè)實(shí)例,這個(gè)實(shí)例是一個(gè)對(duì)象。實(shí)際上一個(gè)類本質(zhì)上也是一個(gè)對(duì)象,在runtime中用結(jié)構(gòu)體表示。
3.相關(guān)定義
/// 描述類中的一個(gè)方法
typedef struct objc_method *Method;
/// 實(shí)例變量
typedef struct objc_ivar *Ivar;
/// 類別Category
typedef struct objc_category *Category;
/// 類中聲明的屬性
typedef struct objc_property *objc_property_t;
4.類在runtime中的表示
//類在runtime中的表示
struct objc_class {
Class isa;//指針,顧名思義,表示是一個(gè)什么,
//實(shí)例的isa指向類對(duì)象,類對(duì)象的isa指向元類
#if !__OBJC2__
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;//緩存
//一種優(yōu)化,調(diào)用過的方法存入緩存列表,下次調(diào)用先找緩存
struct objc_protocol_list *protocols //協(xié)議列表
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
獲取列表
有時(shí)候會(huì)有這樣的需求,我們需要知道當(dāng)前類中每個(gè)屬性的名字(比如字典轉(zhuǎn)模型,字典的Key和模型對(duì)象的屬性名字不匹配)。
我們可以通過runtime的一系列方法獲取類的一些信息(包括屬性列表,方法列表,成員變量列表,和遵循的協(xié)議列表)。
unsigned int count;? ?
?//獲取屬性列表? ??
objc_property_t *propertyList = class_copyPropertyList([self class], &count);? ? for (unsigned int i=0; i%@", [NSString stringWithUTF8String:propertyName]);? ? }? ? //獲取方法列表? ?
?Method *methodList = class_copyMethodList([self class], &count);? ?
?for (unsigned int i; i%@", NSStringFromSelector(method_getName(method)));? ? }? ? //獲取成員變量列表??
? Ivar *ivarList = class_copyIvarList([self class], &count);? ? for (unsigned int i; i%@", [NSString stringWithUTF8String:ivarName]);? ? }? ?
?//獲取協(xié)議列表? ??
__unsafe_unretained Protocol **protocolList = class_copyProtocolList([self class], &count);? ?
?for (unsigned int i; i%@", [NSString stringWithUTF8String:protocolName]);
}
在Xcode上跑一下看看輸出吧,需要給你當(dāng)前的類寫幾個(gè)屬性,成員變量,方法和協(xié)議,不然獲取的列表是沒有東西的。注意,調(diào)用這些獲取列表的方法別忘記導(dǎo)入頭文件#import<objc/runtime.h>。