原文在此
Runtime
用Objective-C寫的代碼,在運(yùn)行過程中都會被轉(zhuǎn)化成C代碼去執(zhí)行瓶埋。
比如說OC的方法調(diào)用都會轉(zhuǎn)成C函數(shù) id objc_msgSend ( id self, SEL op, ... ); 而OC中的對象其實(shí)在Runtime中都會用結(jié)構(gòu)體來表示捞挥,這個結(jié)構(gòu)體中包含了類名浮创、成員變量列表、方法列表砌函、協(xié)議列表斩披、緩存等。
類在Runtime中的表示:
struct objc_class {
Class isa;//指針讹俊,顧名思義雏掠,表示是一個什么,
//實(shí)例的isa指向類對象劣像,類對象的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 *` */
獲取屬性/方法/協(xié)議列表
unsigned int count;// 用于記錄列表內(nèi)的數(shù)量
// 獲取屬性列表
objc_property_t *propertyList = class_copyPropertyList([UITextField class], &count);
const char *propertyName = property_getName(propertyList[0]); // 獲取第一個
// 獲取方法列表
Method *methodList = class_copyMethodList([UITextField class], &count);
NSString *methodName = NSStringFromSelector(method_getName(methodList[0]))
// 獲取成員變量列表
Ivar *ivarList = class_copyIvarList([UITextField class], &count);
const char *ivarName = ivar_getName(ivarList[0]);
// 可通過此方法設(shè)置TF的placeholderColor
[tf setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
攔截調(diào)用與動態(tài)添加
// 調(diào)用不存在的類方法時觸發(fā)耳奕,默認(rèn)返回NO绑青,可以加上自己的處理后返回YES
+ (BOOL)resolveClassMethod:(SEL)sel;
// 調(diào)用不存在的實(shí)例方法時觸發(fā),默認(rèn)返回NO屋群,可以加上自己的處理后返回YES
+ (BOOL)resolveInstanceMethod:(SEL)sel;
// 將調(diào)用的不存在的方法重定向到一個其他聲明了這個方法的類里去闸婴,返回那個類的target
- (id)forwardingTargetForSelector:(SEL)aSelector;
// 將調(diào)用的不存在的方法打包成 NSInvocation 給你,自己處理后調(diào)用 invokeWithTarget: 方法讓某個類來觸發(fā)
- (void)forwardInvocation:(NSInvocation *)anInvocation;
關(guān)聯(lián)對象
static char associatedObjectKey;
objc_setAssociatedObject(self, &associatedObjectKey, @"我就是要關(guān)聯(lián)的字符串對象內(nèi)容", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
NSString *theString = objc_getAssociatedObject(self, &associatedObjectKey);