iOS运行时runtime及相关Objective-C底层讲解

1.runtime体验

1.1.引言

运行时作为面试题中高阶问题必不可少的一个技能点。经常面试官会问道是否使用过运行时,以及如何使用运行时。并且我认为这个技术算是高阶开发里面一个投机的技巧,绝大多数的UI开发都不会使用runtime,容易出现很严重的问题,并且官方也不是特别推荐使用。所以会导致很多人对运行时没有一个清晰全面的认识,网上资料也很少。所以你一定会有这样的疑问:什么是运行时?在我们的项目中怎么使用运行时?哪些时候可以使用运行时?等等。。

问题:当想在一个分类(category)中添加一个属性时,并且iOS是不允许给扩展类扩展属性的(category相对于子类来说,如果需要添加一个新的变量,则需添加子类。如果只是添加一个新的方法,用Category是比较好的选择。)

答案:使用runtime

1.2.runtime机制

我们都知道Objective-C是C的超集,我们平时写的Objective-C都是最终转成了runtime的C语言代码,所以runtime是一套比较底层的纯C的API,属于C语言库,包含了很多底层C语言的API。

所以,在我们编译时,其实runtime是不存在。只有在运行过程中才去确定对象的类型,方法等等。而我们就可以根据这个特性再程序运行时动态的修改类、对象中的所有属性、方法。

 

我们在使用运行时的地方,都需要包含头文件:#import <objc/runtime.h>。如果是Swift就不需要包含头文件,就可以直接使用了。

1.3.runtime头文件

在iOS 9.3 user/include>objc文件夹下有如下的文件

这些都是runtime相关的头文件,其中我们主要使用的是message.h和runtime.h这2个文件。

  • message.h:主要包含了一些向对象发送消息的函数,这是OC对象方法调用的底层实现。
  • runtime.h:运行时最重要的文件,其中包含了对运行时进行操作的方法。

1.3.1.runtime.h

首先贴上源码

这些类型的定义,对一个类进行了完全的分解,将类定义或者对象的每一个部分都抽象为一个类型type,对操作一个类属性和方法非常方便。OBJC2_UNAVAILABLE标记的属性是Ojective-C 2.0不支持的,但实际上可以用响应的函数获取这些属性,例如:如果想要获取Class的name属性,可以按如下方法获取:

1.3.1.1.函数的定义
  • 对象进行操作的方法一般以object_开头
  • 进行操作的方法一般以class_开头
  • 类或对象的方法进行操作的方法一般以method_开头
  • 成员变量进行操作的方法一般以ivar_开头
  • 属性进行操作的方法一般以property_开头开头
  • 协议进行操作的方法一般以protocol_开头

根据以上的函数的前缀 可以大致了解到层级关系。

对于以objc_开头的方法,则是runtime最终的管家,可以获取内存中类的加载信息,类的列表,关联对象和关联属性等操作。

例如:使用runtime对当前的应用中加载的类进行打印。

1.4.获取对象所有属性名

利用运行时获取对象的所有属性名是可以的,但是变量名获取就得用另外的方法了。我们可以通过class_copyPropertyList方法获取所有的属性名称。

下面我们通过一个Person类来学习,这里的方法没有写成扩展,只是为了简化,将获取属性名的方法直接作为类的实例方法:

下面主要是写如何获取类的所有属性名的方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值