原文在此
Runtime
用Objective-C写的代码,在运行过程中都会被转化成C代码去执行。
比如说OC的方法调用都会转成C函数 id objc_msgSend ( id self, SEL op, ... ); 而OC中的对象其实在Runtime中都会用结构体来表示,这个结构体中包含了类名、成员变量列表、方法列表、协议列表、缓存等。
类在Runtime中的表示:
struct objc_class {
Class isa;//指针,顾名思义,表示是一个什么,
//实例的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;//缓存
//一种优化,调用过的方法存入缓存列表,下次调用先找缓存
struct objc_protocol_list *protocols //协议列表
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
获取属性/方法/协议列表
unsigned int count;// 用于记录列表内的数量
// 获取属性列表
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]);
// 可通过此方法设置TF的placeholderColor
[tf setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
拦截调用与动态添加
// 调用不存在的类方法时触发,默认返回NO,可以加上自己的处理后返回YES
+ (BOOL)resolveClassMethod:(SEL)sel;
// 调用不存在的实例方法时触发,默认返回NO,可以加上自己的处理后返回YES
+ (BOOL)resolveInstanceMethod:(SEL)sel;
// 将调用的不存在的方法重定向到一个其他声明了这个方法的类里去,返回那个类的target
- (id)forwardingTargetForSelector:(SEL)aSelector;
// 将调用的不存在的方法打包成 NSInvocation 给你,自己处理后调用 invokeWithTarget: 方法让某个类来触发
- (void)forwardInvocation:(NSInvocation *)anInvocation;
关联对象
static char associatedObjectKey;
objc_setAssociatedObject(self, &associatedObjectKey, @"我就是要关联的字符串对象内容", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
NSString *theString = objc_getAssociatedObject(self, &associatedObjectKey);