iOS 开发 Runtime 运行时机制 完全解读

前言

在最开始听到runtime的时候,我是感到恐惧的,多么高大上的东西啊!!!后来,开始在网上查一些资料,可是就是只有那么几篇,看了好久,还不知所云,所以就更加恐惧了!!!!后来经过查看documents 以及一些国外大牛的blogs,终于对runtime有了更深刻的了解!

runtime实现的机制是什么

  • runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。
  • 在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者 比如说,下面一个创建对象的方法中.
举例: OC : [[MJPerson alloc] init] 
runtime : objc_msgSend(objc_msgSend("MJPerson" , "alloc"), "init")

runtime 用来干什么呢??用在那些地方呢?怎么用呢?

runtime用来干什么?

runtime是属于OC的底层, 可以进行一些非常底层的操作(用OC是无法现实的, 不好实现)

  • 在程序运行过程中, 动态创建一个类(比如KVO的底层实现)
  • 在程序运行过程中, 动态地为某个类添加属性\方法, 修改属性值\方法
  • 遍历一个类的所有成员变量(属性)\所有方法 例如:我们需要对一个类的属性进行归档解档的时候属性特别的多,这时候,我们就会写很多对应的代码,但是如果使用了runtime就可以动态设置!

runtime用在哪些地方? 怎么用?
应用案例:

#import <objc/runtime.h>
  • 给系统分类添加属性
// 运行时给分类添加属性--get方法
- (UIView *)backgroundView {
    return objc_getAssociatedObject(self, &backgroundViewKey);
}

// 运行时给分类添加属性--set方法
- (void)setBackgroundView:(UIView *)backgroundView {
    objc_setAssociatedObject(self, &backgroundViewKey, backgroundView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
  • 方法交换(黑魔法)
    Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
    // 获取xmg_imageNamed
    Method xmg_imageNamedMethod = class_getClassMethod(self, @selector(xmg_imageNamed:));

    // 交互方法:runtime
    method_exchangeImplementations(imageNamedMethod, xmg_imageNamedMethod);
  • 获取对象属性/私有属性
JDGTextField *phoneNumeber = [[JDGTextField alloc] init];
    phoneNumeber.placeholder = @"请输入手机号";
    [phoneNumeber setValue:[UIColor colorWithRed:246.0/255 green:222.0/255 blue:186.0/255 alpha:1.0] forKeyPath:@"_placeholderLabel.textColor"];
  • 字典转模型(KVC)
[self setValuesForKeysWithDictionary:dict];
  • KVC 动态获取属性–下拉刷新
self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
  • 归档解档
1NSData-归档2Person对象到同一文件中

归档(编码)

// 新建一块可变数据区
NSMutableData *data = [NSMutableData data];
// 将数据区连接到一个NSKeyedArchiver对象
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
// 开始存档对象,存档的数据都会存储到NSMutableData中
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
// 存档完毕(一定要调用这个方法)
[archiver finishEncoding];
// 将存档的数据写入文件
[data writeToFile:path atomically:YES];

2NSData-从同一文件中恢复2Person对象

恢复(解码)

// 从文件中读取数据
NSData *data = [NSData dataWithContentsOfFile:path];
// 根据数据,解析成一个NSKeyedUnarchiver对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
// 恢复完毕
[unarchiver finishDecoding];
  • NSClassFromString
NSString *vcName = obj[JDGRootVcName];
        Class vcClass = NSClassFromString(vcName);
        UIViewController *vc = [[vcClass alloc] init];
  • block

runtime相关函数

objc_msgSend : 给对象发送消息
class_copyMethodList : 遍历某个类所有的方法
class_copyIvarList : 遍历某个类所有的成员变量
class_..... 这是我们学习runtime必须知道的函数!

runtime原理机制

—未完待续

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值