iOS-了解Runtime

一.Runtime是什么?

Runtime也叫运行时态,是iOS底层用C语言函数和汇编语言封装的一套API,我们的程序在运行过程中,都是基于Runtime实现的。

二.Runtime的消息机制

//例如我们创建一个People类
People * pe = [[People alloc] init];

//通过objc_msgSend函数来发送消息,转换为:
id pe = objc_msgSend(objc_msgSend([Person class], @selector(alloc)), @selector(init));

//再通过objc_getClass和sel_registerName函数往下转换为:
id pe = objc_msgSend(objc_msgSend(objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
  • 这就是消息发送机制。
  • 苹果封装了消息机制,一般不建议大家使用底层的消息机制。

这是下面讲的Demo下载地址

二.Runtime演示一

  • 这里用OC的归档和解档来当例子,不知道可以查看前面我写的 iOS归档和解档

  • 我们知道OC的序列化是把model转化为二进制存储,使用也很方便,但是如果一个model的属性很多的话,在写归档或者解档的时候 对我们来说就成了一种负担,这里就用到Runtime来解决。
  • 下面进入主题

    • 导入头文件(Runtime系统是具有公共接口的动态共享库。头文件存放于/usr/include/objc目录下,这意味着我们使用时只需要引入objc/Runtime.h头文件即可。)
    1.导入头文件 #import <objc/runtime.h>
    2.获取类成员变量列表,返回类的所有属性和变量
      unsigned int count = 0;
      Ivar *ivars = class_copyIvarList([UIButton class], &count);
      //第一个参数填写类(这里写button),第二个参数count为类成员的数量
    3.通过指针取出button数据
      Ivar ivar = ivars[0]; (默认第一个可以通过循环获取每个数据)
    4.获取数据name,返回C的字符串
      const char *name = ivar_getName(ivar);
      //转换成OC字符串(这里获取到成员变量的name)
      NSString *nameStr = [NSString stringWithUTF8String:name];
    5.nameStr就是获取到button的一些私有变量
    
    • 解档和归档用runtime来获取成员变量修改成如图所示(图中注释的三行为之前的原代码)
      归档

      解档
  • 下面我删除app重新运行一下,ViewController里面写两个button,和两个对应的点击方法(归档方法和解档方法)

    运行之后先点击一下解档按钮
    此时控制台输出(解档方法里面有个输出)

    发现输出数据都是null,Don't worry😺,这是因为还有没归档,所以解档是没有数据的。 接下来我点击一下归档,然后我再点击一下解档,这个时候就可以看到有输出信息了,说明用runtime改写成功。(是不是很简单呢😊)
  • 小结:通过runtime可以获取到类的一些私有变量和私有方法。

二.Runtime演示二

  • 首先我们都知道NSURL * url = [NSURL URLWithString:@"这里填写请求的URL字符串"];里面填写请求URL字符串,如果拼出来的字符串 http://baidu.com?p1=%+&sd f&p2=这里有汉字中有汉字、特殊符号&%和空格等,必须进行转译才能正确访问,这个时候就需要对 URL 进行 Encode。如果填写的URL里面有中文的话,返回的URL对象为nil(这里只举例包含汉字的URL访问)


    那么我能不能封装一下,在调用方法内部的时候如果请求的URL包含文字就调用自己写的方法实现,如果不包含文字就调用系统原来的方法实现,我能不能截取到这个方法改成我自己的方法呢?这里我们就可以用Runtime来解决。

    • 首先创建一个URL的类别,CNSURL
    • 在NSURL+CNSURL.m里面,重写一个CHURLWithString方法(isContainChinese方法用来判断是否包含中文)如图所示

      上图中要注意方法里面调用本方法其实是调用NSURLWithString的方法实现,这一点一定要搞清楚。
    • 通过进行方法交换来实现:

    1.导入头文件 #import <objc/runtime.h>
    2.写load方法,因为load方法在程序一进来的时候就开始执行,比main函数都早。
    3.在load方法里 class_getClassMethod(类, 方法名) 用来获取类方法。
      class_getInstanceMethod(类, 方法名) 用来获取实例方法。
      method_exchangeImplementations(方法一, 方法二) 用来交换两个方法的实现。
    
    • 在ViewController中实现两个按钮一个有文字URL,一个没有文字URL

    • 点击第一个没有文字的URL,控制台输出
    • 点击第二个有文字的URL,控制台输出
    • 说明点击按钮的时候调用URLWithString方法(第一个输出打印的是判断文字的输出,然后打印出编码处理的输出,最后打印出上图中的一行输出) 其实是调用了NSURL+CNSURL里面的CHURLWithString方法。
  • 小结:在OC的Runtime中任何方法的调用其内部都是发送消息,上面是通过发送消息来找到方法编号(SEL),通过方法编号来找到方法实现(IMP),这里把方法实现改成CHURLWithString这个的方法实现,这叫方法欺骗。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 对于从事 iOS 开发人员来说,所有的人都会答出【runtime 是运行时】什么情况下用runtime?大部分人能...
    梦夜繁星阅读 3,697评论 7 64
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,678评论 0 9
  • 本文分为4个部分 1.介绍OC和C语言之间的转换 2.介绍运行时和相关术语 3.介绍消息发送机制已及怎样找到函数实...
    一片枫叶随风舞阅读 302评论 0 1
  • 幸福莲发起共享美容财富新思维 大众创新、万众创业 新时代的列车缔造新的财富中心 您选择就是顺势而为,站在风口上前行...
    李紫誠阅读 408评论 0 0
  • 这个月以来,最不想过的,是星期二。老师的测验我已经两次都没过了。我不明白,一个大学老师为何如此苛刻,我因为一个符号...
    谦哥xxx阅读 246评论 0 1