Runtime 10种用法

作者: 二斤寂寞 | 来源:发表于2018-05-25 19:05 被阅读49次

转载runtime文章收集

runtime简介:

Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的。

人在江湖飘,身不由己啊。循环不停的业务,都几乎没有时间去总结。就是会用一些,但是真正想下runtime这个。自己还真说不出个所以然来。

爬爬帖子,给自己留个印儿。

OC最实用的runtime总结,面试、工作你看我就足够了!
让你快速上手Runtime
runtime详解
详解runtime运行时机制
万能控制器跳转

看一张图:


image.png

十大用法:

  • 1.将某些OC代码转为运行时代码,探究底层,比如block的实现原理
  • 2.拦截系统自带的方法调用(Swizzle 黑魔法),也可以说成对系统的方法进行替换,比如拦截imageNamed:、viewDidLoad、alloc
  • 3.实现分类也可以增加属性;
  • 4.实现NSCoding的自动归档和自动解档;(不用对每个属性edcode和decode了,如果几十个属性一个个的encode和decode真的很麻烦啊,使用运行时可以遍历出每个对象的属性,数组的方式遍历eccode,decode)
  • 5.实现字典和模型的自动转换(核心就是可以遍历出字典中的每个属性,json解析中大牛框架都用了这个特性,包括MJEXtension,YYModel,jsonModel都是将json转换为字典,再遍历字典中的每个属性来进行modle的转换)。
  • 6.动态增加方法 (动态的为某个类或对象增加一个方法,摘录文章中有详细介绍)
  • 7.动态变量控制 (动态对某个对象的变量的值进行替换,摘录文章有详细介绍)
  • 8.实现万能控制器跳转

产品来一变态需求,推送过来的消息,要跳转到任意控制器.利用runtime动态生成对象、属性、方法这特性,我们可以先跟服务端商量好,定义跳转规则,比如要跳转到A控制器,需要传属性id、type,那么服务端返回字典给我,里面有控制器名,两个属性名跟属性值,客户端就可以根据控制器名生成对象,再用kvc给对象赋值,这样就搞定了。

组件化其实也用到了runtime,根据url,动态获取到类,参数等。可以参考蘑菇街开源项目

  • 9.插件开发
  • 10.Jspath 热更新 也是使用运行时,jspatch 基本上算是黑科技,在线修复版本bug,虽然被苹果爸爸禁止使用了一段时间,后来好像谈妥了,又可以付费使用了。
总结:

综上所述,runtime核心用法有一下三点。

Method class_getClassMethod(Class cls , SEL name) //获得某个类的类方法
Method class_getInstanceMethod(Class cls , SEL name) // 获得某个类的实例对象方法
void method_exchangeImplementations(Method m1 , Method m2) // 交换两个方法的实现
1、方法简单的交换

下面通过runtime 实现方法交换,类方法用class_getClassMethod ,对象方法用class_getInstanceMethod

// 获取两个类的类方法
Method m1 = class_getClassMethod([Person class], @selector(run));
Method m2 = class_getClassMethod([Person class], @selector(study));
// 开始交换方法实现
method_exchangeImplementations(m1, m2);
// 交换后,先打印学习,再打印跑!
[Person run];
[Person study];
2、拦截系统方法

步骤:
1、为UIImage建一个分类(UIImage+Category)
2、在分类中实现一个自定义方法,方法中写要在系统方法中加入的语句,比如版本判断

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

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

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

注意:自定义方法中最后一定要再调用一下系统的方法,让其有加载图片的功能,但是由于方法交换,系统的方法名已经变成了我们自定义的方法名(有点绕,就是用我们的名字能调用系统的方法,用系统的名字能调用我们的方法),这就实现了系统方法的拦截!

3、获得一个类的所有成员变量
Ivar *class_copyIvarList(Class cls , unsigned int *outCount) //获得一个类的所有成员变量
const char *ivar_getName(Ivar v) //获得成员变量的名字 
const char *ivar_getTypeEndcoding(Ivar v) //获得成员变量的类型
//获取Person类中所有成员变量的名字和类型
unsigned int outCount = 0;
Ivar *ivars = class_copyIvarList([Person class], &outCount);

// 遍历所有成员变量
for (int i = 0; i < outCount; i++) {
    // 取出i位置对应的成员变量
    Ivar ivar = ivars[i];
    const char *name = ivar_getName(ivar);
    const char *type = ivar_getTypeEncoding(ivar);
    NSLog(@"成员变量名:%s 成员变量类型:%s",name,type);
}
// 注意释放内存!
free(ivars);

相关文章

  • iOS面试点文章链接

    runtime基础方法、用法、消息转发、super: runtime 完整总结 runloop源码、runloop...

  • RunTime用法

    一、什么是RunTime iOS开发过程中,我们一直在与Runtime打交道,可什么是Runtime呢? 对比C语...

  • runtime用法

    在之前学习runtime的过程中,我发现方法交换有两种写法,一开始对对一种写法不太能理解,后来自己写demo来试验...

  • runtime用法

    1.监听网络状态 2.添加分类属性(set / get_assocaite关联) 3.获取类的成员变量以及属性等(...

  • iOS-runtime相关

    本篇涵盖runtime的解析、应用等. 1.runtime快速入门和实战2.Runtime 10种用法(没有比这更...

  • Docker 命令

    用法 Usage: A self-sufficient runtime for containers. 选项 Op...

  • Runtime消息转发及其应用

      之前写过文章Runtime的常见用法里面有介绍过利用Objective-C的Runtime特性来给Catego...

  • Runtime快速上手(1)

    依照惯例跳过Runtime的介绍,这里只介绍Runtime的基本用法和简单应用例子。 一、获取属性列表 输出结果:...

  • runtime的用法

    1.使用runtime改变变量值 2.使用runtime交换方法 3.使用runtime添加方法 4.使用runt...

  • runtime的用法

    最近在研究runtime 主要是想好好的装一波 无奈 看过了 唐巧大大的runtime介绍 看的我是脑袋直疼,看来...

网友评论

    本文标题:Runtime 10种用法

    本文链接:https://www.haomeiwen.com/subject/kymujftx.html