美文网首页
runtime的理解和在实际项目中的应用

runtime的理解和在实际项目中的应用

作者: mrChan1234 | 来源:发表于2017-11-13 14:35 被阅读0次

1.runtime(运行时机制)是什么?

runtime是属于OC的底层,是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API,可以进行一些非常底层的操作(用OC是无法现实的, 不好实现)。 在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者,runtime可以让我们更好的理解OC这门语言

2.runtime的基本理解

Class类的本质就是一个结构体指针类型,其内部结构如下所示:

Class的内部结构

Class 也有一个 isa 指针,指向其所属的元类(metaClass)。

·super_class:指向其超类。

·name:是类名。

·version:是类的版本信息。

·info:是类的详情。

·instance_size:是该类的实例对象的大小。

·ivars:指向该类的成员变量列表。

·methodLists:指向该类的实例方法列表,它将方法选择器和方法实现地址联系起来。methodLists 是指向 ·objc_method_list 指针的指针,也就是说可以动态修改 *methodLists 的值来添加成员方法,而这里就是Categeory的工作原理,同时也解释了Categeory不能添加属性。

·cache:Runtime 系统会把被调用的方法存到 cache 中(理论上讲一个方法如果被调用,那么它有可能今后还会被调用),下次查找的时候效率更高。

·protocols:指向该类的协议列表

说了这么多的抽象的东西,可能大家有点难以理解,那么方法调用是如何一步一步工作起来的呢?我们可以应用clang命令来查看OC转为C的代码看下大概,比如下面的代码:

Cell.m

使用clang命令转为cpp文件如下:

Cell.cpp

Cell.cpp里面展示了方法后面的内部实现,可以看到方法调用的本质是发送消息[reciever function]被转换成objc_msgSend(reciever,selector);看一个cell初始化里面做了什么事情:

Cell.cpp

[self addsubView]被转换成了((void(*)(id, SEL, UIView *))(void*)objc_msgSend)((id)((UIView *(*)(id, SEL))(void*)objc_msgSend)((id)self, sel_registerName("contentView")), sel_registerName("addSubview:"), (UIView *)(*(UIButton **)((char*)self + OBJC_IVAR_$_Cell$_check)));

objc_msgSend 函数被定义在 objc/message.h 目录下,其函数原型是这样的:

OBJC_EXPORT void objc_msgSend(void/* id self, SEL op, ... */)  这就是方法调用的本质。

当我们调用一个方法时,大致经历了以下过程:

首先,Runtime 系统会把方法调用转化为消息发送,即 objc_msgSend,并且把方法的调用者,和方法选择器,当做参数传递过去,此时,方法的调用者会通过 isa 指针来找到其所属的类,然后在 cache 或者 methodLists 中查找该方法,找得到就跳到对应的方法去执行。如果在类中没有找到该方法,则通过 super_class 往上一级超类查找 这也就是为什么继承了一个类并重写父类方法会首先执行重写的方法而不是执行父类方法了(如果一直找到 NSObject 都没有找到该方法的话,这种情况,就会报错unrecognized selector sent to instance xxxxx。

前面我们说 methodLists 指向该类的实例方法列表,实例方法即-方法,那么类方法(+方法)存储在哪儿呢?类方法被存储在元类中,Class 通过 isa 指针即可找到其所属的元类。

我们再看下这段代码:

objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Cell"))}, sel_registerName("initWithStyle:reuseIdentifier:"), (UITableViewCellStyle)style, (NSString *_Nullable)reuseIdentifier);

这是调用super init...方法.当我们调用 [super selector] 时,Runtime 会调用 objc_msgSendSuper 方法,objc_msgSendSuper 方法有两个参数,super 和 op,Runtime 会把 selector 方法选择器赋值给 op。而 super 是一个 objc_super 结构体指针,这就是调用super方法runtime做的事情.看到这里,是不是对OC的了解好像是更进了一步??

3.runtime的应用都有哪些?

1.给对象关联属性

像给UIViewController关联一个可变数组用以加网络操作:

2.归档和解归档

以前的model属性要实现归档和解归档都是这样写的:

傻瓜式的归档解归档

可是问题来了,要是一个class有100个属性呢?!,于是runtime可以很好的帮助你获取到一个class的所有成员变量,如下所示:

runtime归档和解归档

这也就是著名的三方框架:MJExtendsion的核心思想,MJExtendsion就是大量应用了runtime来获取类的所有属性来进行操作.

3.model和json之间的互相转换,大家可以去了解下MJExtendsion的源代码.

4.方法交换,动态方法解析(慎用).

相关文章

  • runtime的理解和在实际项目中的应用

    1.runtime(运行时机制)是什么? runtime是属于OC的底层,是一套比较底层的纯C语言API, 属于1...

  • runtime在实际项目中的应用

    平时觉得runtime都是大神用的,但是通过慢慢的学习,在实际项目中运用runtime,某些时候确实感觉挺牛逼的....

  • Runtime的应用

    Runtime的基本属性和消息转发机制已经介绍过了,下面来了解一些Runtime提供的api在实际项目中的应用。 ...

  • runtime的实际应用

    1、使用关联对象动态给分类添加属性 使用关联对象,可以为类添加Category中的属性,我们可以为现有类添加一些实...

  • RunTime实际应用

    一. RunTime简介 RunTime简称运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是...

  • Runtime:实际应用

    一、遍历一个类所有的成员变量,实现一键归档解档二、使用Method Swizzling 1、从全局上为项目做一些统...

  • RunTime的应用和理解

    runtime的理解和应用 项目中经常会有一些的功能模块用到runtime,最近也在学习它.对于要不要阅读runt...

  • iOS Runtime的实际应用

    iOS Runtime的实际应用 导入 见题知意,这篇文章并不是告诉你什么是Runtime机制以及它的原理,本文主...

  • Runtime全面剖析之原理篇

    如果想了解Runtime的实际应用请看Runtime全面剖析之简单使用 一:Runtime简介二: Runtime...

  • runtime学习(四):runtime的实际应用

    注:本文不是原创,只是在学习中做的整理和笔记,以便自己以后更好的复习。原文来自runtime从入门到精通系列 有关...

网友评论

      本文标题:runtime的理解和在实际项目中的应用

      本文链接:https://www.haomeiwen.com/subject/rjnbmxtx.html