Runtime-b
感谢大神分享
依旧是网上很多runtime的资料,依旧是看不懂,,,这里给大家转化一下runtime,使它由隐晦难懂变得通俗易懂。
(虽然截图和语言组织的有些凌乱,但是大家还是一点一点的阅读下去吧,可以新建一个工程,跟着我写的一步一步的自己走一遍,会有帮助的。)
关于runtime理论性的东西可以参考我们同事hah的初识runtime(我俩的文章名字居然差不多)
本文参照:教你快速上手Runtime。谢谢该文作者峥吖峥老师。有兴趣的也可以去峥老师的博客看看去。
另外哪里写的不对,可以给我留言,我会及时改进的,谢谢大家。
在这里我们对runtime进行如下的介绍:
1、runtime的简单介绍
2、runtime的消息发送
3、用runtime交换方法
4、动态添加方法
5、动态添加属性
6、runtime替换KVC,进行字典转换
下边开始我们的通俗易懂的路程:
1、配置环境:新建一个工程,在appdelegate里面将viewcontroller设置为rootcontroller,方便查看打印信息。
创建一个person类,继承自NSObject,下图的PersonViewController无用。
然后再看一下目前的工程文件结构:
按照网上教程我们开始runtime的各个方法的实现。
2、发送消息。举例:实例方法和类方法的调用原理。
我们建立一个继承于NSObject的Person
在.m中分别实现实例方法和类方法:
然后在viewcontroller加入头文件:#import "Person.h"、#import <objc/message.h>
方法的调用有两种,调用实例方法和调用类方法。我们用runtime去观察这两种方法的实质。
1、viewDidLoad里面实现Person的实例化,并用这个实例调用Person里面的实例方法;
2、直接用Preson类名或类对象调用类方法。
此时我们可以看到
但是按照网上教程上图蓝色框框里面的也应该可以放开注释的,可是不知道为什么我的放开注释以后会爆红:
不知道是为什么(如果大家谁知道怎么回事,还烦请留言告诉我,再次谢谢大家了),,,所以这里的runtime并不友好。
哎,终于知道怎么回事了,还是同事hah帮忙解决的:头文件导入错了,应该是导入:#import <objc/runtime.h>
导入#import<objc/messge.h>也可以调用objc_msgSend()这个方法,但是不能传参,而导入#import<objc/runtime.h>,会出现这个方法:objc_msgSend(id, SEL, ...),是可以传参数的.
在这里有的网友提到另外一种解决该问题的方案:谢谢北京-吴露。方案是:引入头文件<objc/objc-runtime>,command+点击进入这个方法,我们会看到下边的
也就是说这个头文件把runtime和message都包含了,不过建议还是单独引入,因为这两个头文件里面的方法很多都类似,容易混淆,区别在于方法是否可以传参数。就像上边我们举例的问题。
打印结果:
其实这里咱们可以看到网上教程的注释:不管是实例方法还是类方法,其本质就是让对象或者类对象发送消息,即我们在OC中调用的实例方法和类方法在runtime运行时的时候实际上是转化成C语言的发送消息的语句。
按照网上教程说的:消息机制原理:对象根据方法编号SEL去映射表查找对应的方法实现
其实说的就是:找到对应的实例方法或者类方法。
最后,这里的runtime的使用并不实用。
3、交换方法。
其实写完下边的代码,在通过理解,你会发现这中所谓的“交换方法”实际上就是系统方法的重写、扩展、再替换回去的过程。
首先我们看一下demo里面viewcontroller的结构(同样的personviewcontroller无用,忽略掉,这里的<objc/message.h>最好是换成#import<objc/runtime.h>):
然后我们看viewDidLoad里面,在这里我们没有做什么操作,只是命名了一个image:这里我们的图片是在工程文件中的,所以走到替换方法里面的时候会判断不为空,所以对应的打印信息“加载空的图片”就不会打印出来。
按照网上教程我们进行步骤一的操作,写一个名字叫做+ (instancetype)imageWithName:(NSString*)name的类方法。这个方法是为了替换的时候准备的。
然后我们进行步骤二,这个步骤二很关键,就是替换的核心所在。
注意:两个方法。前面一个是准备好的方法,后边一个是系统的方法,要用第一个方法换掉第二个方法,这里需要注意替换顺序。
当我们将viewDidLoad里面的image换成一个空的图片的时候
我们看到打印信息
是走了图片为空的if判断里面的。
所以,这个方法可以看成是网络请求一张图片,如果请求失败,可以用默认的图片进行展示,就像下边的方法,网络请求失败的时候会展示一张默认图。
当然,这里不是说runtime这么高大上的方法仅仅能实现这么low的功能,仅做示例而已。
其实这个方法替换可以用在线下替换线上代码里面,“黑魔法”,我还不会,只是听说过。下边继续学习runtime其他的方法。
4、动态添加方法。
动态添加方法,咱们的person类.h里面用到了分类:
在这里拓展一下类扩展的知识:类扩展与分类的区别。谢谢作者:Mitchell孟晨
在这里大家是不是会想到我们的面试题中:
有的还是用英语问的:
类的作用。参考自category解析。如果大家对类别特别感兴趣可以参考深入解析OC中的Category
当我们在类中添加@interface的时候:
会出现上图中的3个。
第一个就是类:继承自谁。
第二个是分类,就是分类。
类扩展与分类的区别中有举例说明:虽然我们在分类中声明属性不会报错,但是@property并没有自动为我们设置的属性生成set、get方法。
第三个就是extension。类扩展。
再看上述中有一句话是这样说的:
类扩展的作用:
person类.m中:
viewcontroller里面:
这里没有实现eat4方法,所以会在viewcontroller中的viewdidload里面调用eat4的时候,会调用这个方法处理,并且把对应的方法列表传过来。用来判断为实现的方法是不是我们想要动态添加的方法。
这里注意的是,峥老师教程里面在调用class_addMethod(self,@selector(eat4), (IMP)eatt,"v@:");这个方法的时候,第三个参数前面并没有添加“(IMP)”,不添加这个IMP,会报黄:
说的什么不清楚,意思就是叫你添加上IMP。
拓展一下performSelector调用和直接调用的区别:
准备好了,我们看打印结果:
这里我们可以看到NSStringFromSelector(sel)调用的就是eat4。
扯了这么多怎么用,到底这个动态添加方法到底是用来干什么的呢,看看众多网友的理解。翻了好多,就下边的两个解释比较靠谱,大家凑合着看吧:
当然还有最一开始咱们引入动态添加的时候的目的:
不忘初心,方得始终。
5、动态添加属性。
想知道原理的请移步OC Associated Objects实现原理
原理:给一个类声明属性,其实本质就是给这个类添加关联,并不是直接把这个值的内存空间添加到类存空间。
看结构,添加了一个NSObject的分类:
分类的.h文件,将set方法和name外漏,方便在viewcontroller里面调用。
分类的.m文件,set方法和name的实现。
最后看viewcontroller里面,引入分类的头文件,然后实例化NSObject,调用objc1的name。
最后的打印结果:
tips:其实呢这个动态添加属性,是在哪里用到的呢?具体的我也说不上来。其实按照我的理解,咱们这里所谓的动态添加属性,是在分类上边添加的属性,那么我就想了,为什么我不能在类自己本身上边添加属性呢?对吧?为什么非要在分类上边添加呢,还整了个动态添加属性,麻烦不?!原因有两个:
1)如果你的类自己本身里面的逻辑或者代码比较多,而需求是新加一个功能,那么就可以在分类上边添加,因为分类和继承还是有区别的。咱们这样理解啊:如果你用的是继承,那么在子类a里面新添加的属性和方法,在父类以及其他继承父类的子类b里面是不能用新添加的属性和方法的,(有点绕)。但是分类就行,你在分类里面新添加了属性和方法,那么在其他用到这个类自己的地方,是可以用新添加的属性和方法的。好像和公有性、私有性有点关系。
2)给系统的类添加属性。像UIView、UIImageView、UILabel、UIButton等等系统的类,你觉得系统的类里面的属性不够用(当然,像我这种小白还是觉得够用的,关键不知道各个类里面除了经常用的还有啥,,,)就可以自己添加属性,当然了,在MJ和SDWebimage里面其实也能看到动态添加属性的影子,只不过是我们大多数人没有进入人家里面去看具体的代码。同事hah在runtime初识里面也提到了这个:
6、字典转模型
峥老师说的“字典转模型的方式一:KVC”这个就是咱们平时JSON解析的时候经常用到的,这里不作进一步解释,看看峥老师说的用runtime字典转模型的方式。
没搞明白。。。
先用KVC吧。
总的来说,即便咱们知道了runtime是怎么用的,但是没有合适的环境使用runtime,也是白搭。所以,咱们现在能做的就是先了解runtime,随时记在心中,以后哪里能够用到的,可以尝试着用runtime的特性和上述几个方法来实现,甚至于用runtime解决bug。
另外这里有很多关于runtime的集合,大家可以参考:runtime专题
原文链接:http://www.jianshu.com/p/4fd0ef1a144b
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
Runtime-b的更多相关文章
- 魅力 .NET:从 Mono、.NET Core 说起
前段时间,被问了这样一个问题:.NET 应用程序是怎么运行的? 当时大概愣了好久,好像也没说出个所以然,得到的回复是:这是 .NET 程序员最基本的...呵呵! 微软开源,其实不只是对 .NET 本身 ...
- .NET:从 Mono、.NET Core 说起
魅力 .NET:从 Mono..NET Core 说起 前段时间,被问了这样一个问题:.NET 应用程序是怎么运行的? 当时大概愣了好久,好像也没说出个所以然,得到的回复是:这是 .NET 程序员最基 ...
- 魅力 .NET:从 Mono、.NET Core[转]
前段时间,被问了这样一个问题:.NET 应用程序是怎么运行的? 当时大概愣了好久,好像也没说出个所以然,得到的回复是:这是 .NET 程序员最基本的...呵呵! 微软开源,其实不只是对 .NET 本身 ...
- Ant + ivy的安装
有了Ivy的帮忙,我们不需要为了一个库依赖管理而舍弃Ant去学那个难搞的Maven了. 基本配置步骤如下: 1.copy Ivy插件到ant_home/lib下: ivy安装 简单的安装方法: 直 ...
- 刨根问底Objective-C Runtime
http://chun.tips/blog/2014/11/05/bao-gen-wen-di-objective%5Bnil%5Dc-runtime-(2)%5Bnil%5D-object-and- ...
- ArcGIS Runtime SDK for iOS开发地图图层-图形图层
注:本文翻译自:https://developers.arcgis.com/ios/objective-c/guide/creating-a-graphics-layer.htm 创建图 ...
- 刨根问底Objective-C Runtime(4)- 成员变量与属性
http://chun.tips/blog/2014/11/08/bao-gen-wen-di-objective[nil]c-runtime(4)[nil]-cheng-yuan-bian-lian ...
- Objective-O Runtime 运行时初体验
Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...
- 【腾讯Bugly干货分享】移动App入侵与逆向破解技术-iOS篇
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e0acc896e9ebb6865f321 如果您有耐心看完这篇文章,您将懂 ...
随机推荐
- 键盘事件与JS Filter
今天在写一个JS输入文本过滤的程序,本来我的设想是在keypress事件中获取按下的键,然后再进行判断,这样的话总是出错,最后终于明白自己把事件的发生顺序搞错了,应该是先keydown,然后是keyp ...
- 今日又遇无法启动apache
前几天安装了.NET要用到的MSSERVER,之后apache就running none of service. 把微软的MSSERVER停用掉服务就没问题.哪部分冲突了
- .Net训练营优惠有条件 做到立减800元大钞
.NET 是 Microsoft XML Web services 平台.XML Web services 允许应用程序通过 Internet 进行通讯和共享数据,而不管所采用的是哪种操作系统.设备或 ...
- 用Ajax去读取服务器端的XML格式的数据
<html> <head></head> <script type="text/javascript"> /*---定义一个全局变量 ...
- Android怎样改动app不在多任务列表中显示
在实际开发中,我们希望某些activity或者应用程序不在多任务列表中显示,即长按Home键或者多任务button键不显示近期执行的程序,我们能够在对应应用程序的AndroidManifest.xml ...
- SQL Server与Oracle对比学习:表的管理和组织
http://blog.csdn.net/weiwenhp/article/details/8088979 我们知道数据库,顾名思义.最重要的东东就是管理数据,而数据在系统中主要是保存在表(table ...
- (转载)OSI七层参考模型和TCP/IP四层参考模型
Mallory 网络模型概念浅析 网络模型一般是指OSI七层参考模型和TCP/IP四层参考模型. #只是一种设计==模型# Open System Interconnect的缩写,意为开放式系统互 ...
- CSS hack常用方案(摘选)
邮箱因为默认了line-height?:170%,导致采用table元素时继承问题,可以采用line-height:50% 很好解决. 常 在使用float时,后面的显示不正常,因为继承了float了 ...
- jQuery Ajax 实例 全解析
jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 废话少说,直接进入正题,我们先来看一些简单的方法,这些方法都是 ...
- javascript异步加载详解(转)
本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...