iOS 开发 Runtime 运行时机制 完全解读
程序员文章站
2022-06-03 08:16:11
前言
在最开始听到runtime的时候,我是感到恐惧的,多么高大上的东西啊!!!后来,开始在网上查一些资料,可是就是只有那么几篇,看了好久,还不知所云,所以就更加恐惧了!!!!后来经过查看docum...
前言
在最开始听到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给分类添加属性
// 运行时给分类添加属性--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];归档解档
1)nsdata-归档2个person对象到同一文件中 归档(编码) // 新建一块可变数据区 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]; 2)nsdata-从同一文件中恢复2个person对象 恢复(解码) // 从文件中读取数据 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原理机制
—未完待续