runtime

runtime_第1张图片
runtime.png

1.将某些OC代码转为运行时代码,探究底层,比如block的实现原理;
2.拦截系统自带的方法调用(Swizzle 黑魔法),也可以说成对系统的方法进行替换,比如拦截imageNamed:、viewDidLoad、alloc;

a、为UIImage建一个分类(UIImage+Category)

b、在分类中实现一个自定义方法,方法中写要在系统方法中加入的语句,比如版本判断[参考 ]

+ (UIImage*)xh_imageNamed:(NSString*)name {
 
doubleversion = [[UIDevicecurrentDevice].systemVersiondoubleValue];
 
if(version >=7.0) {
 
// 如果系统版本是7.0以上,使用另外一套文件名结尾是‘_os7’的扁平化图片
 
name = [name stringByAppendingString:@"_os7"];    }
 
return[UIImagexh_imageNamed:name];
 
}

分类中重写UIImage的load方法,实现方法的交换(只要能让其执行一次方法交换语句,load再合适不过了)

+ (void)load {
 
// 获取两个类的类方法
 
Method  m1 = class_getClassMethod([UIImageclass],@selector(imageNamed:));  
 
Method m2 = class_getClassMethod([UIImageclass],@selector(xh_imageNamed:));
 
// 开始交换方法实现
 
method_exchangeImplementations(m1, m2);
 
}

3.实现分类也可以增加属性;

4.实现NSCoding的自动归档和自动解档;(不用对每个属性edcode和decode了,如果几十个属性一个个的encode和decode真的很麻烦啊,使用运行时可以遍历出每个对象的属性,数组的方式遍历eccode,decode);

- (void)encodeWithCoder:(NSCoder *)encoder{
unsigned int count = 0;
Ivar * ivars = class_copyIvarList([Movie class],&count);
for (int i = 0; i < count; i++){
  // 取出i位置对应的成员变量
  Ivar ivar = ivars[i];
  // 查看成员变量
   const char * name = ivar_getName(ivar);
   NSString * key = [NSString stringWithUTF8String:name];
   id value = [self valueForKey:key];
   [encoder encodeObject:value forKey:key];
 }
 free(ivars);
}

- (id)initWithCoder:(NSCoder *)decoder{
if (self = [super init]) {
unsigned int count = 0;
Ivar *  ivars = class_copyIvarList([Movie class],&count);
for (int i = 0; i < count; i++){
  // 取出i位置对应的成员变量
  Ivar ivar = ivars[i];
  // 查看成员变量
   const char * name = ivar_getName(ivar);
   NSString * key = [NSString stringWithUTF8String:name];
id value = [decoder decodeObjectForKey:key];
[self setValue:value forKey:key];
}
free(ivars);
}
return self;
}

5.实现字典和模型的自动转换(核心就是可以遍历出字典中的每个属性,json解析中大牛框架都用了这个特性,包括MJEXtension,YYModel,jsonModel都是将json转换为字典,再遍历字典中的每个属性来进行modle的转换)。

6 动态增加方法 动态的为某个类或对象增加一个方法

7 动态变量控制 动态对某个对象的变量的值进行替换

8 实现万能控制器跳转
产品来一变态需求,推送过来的消息,要跳转到任意控制器.利用runtime动态生成对象、属性、方法这特性,我们可以先跟服务端商量好,定义跳转规则,比如要跳转到A控制器,需要传属性id、type,那么服务端返回字典给我,里面有控制器名,两个属性名跟属性值,客户端就可以根据控制器名生成对象,再用kvc给对象赋值,这样就搞定了;
9 插件开发
插件入门
XCode 有个很坑爹的地方,就是它并不官方支持插件开发,官方没有文档,XCode 也没有开源,但由于 XCode 是 Objective-C 写的,OC 动态性太强大,导致在这么封闭的情况下民间还是可以做出各种插件,其核心开发方式就是:
dump 出 Xcode 所有头文件,知道 Xcode 里有哪些类和接口。
通过头文件方法名猜测方法的作用,swizzle 这些方法,插入自己的代码实现插件逻辑。
通过 NSNotificationCenter 监听各种事件的发生。

10 Jspath 也是使用运行时,jspatch 基本上算是黑科技,在线修复版本bug,微信都使用了这个技术.

你可能感兴趣的:(runtime)