iOS Runtime简单使用

原文在此

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);

Demo地址

你可能感兴趣的:(iOS Runtime简单使用)