结构体中函数应该怎样定义才能返回值_Runtime数据结构详解

我们先看Runtime整体的数据结构如下图:

a8ab5b60836cb5f118bedaf666bf4b20.png

初识objc_object

我们平时用到的所有的对象都是id类型,而id对象在runtime中都被定义为objc_object 的结构体。

objc_object的结构体中定义中包含以下五个部分:

1、 isa_t类型的isa

37cf88f382dba8a2055c00c173f55d61.png

2、 isa操作相关

b911e6c504a941f9b7bb489f467c3bcd.png

3、 弱引用相关方法-可以标记改对象是否包含一些弱引用

450ebb33e2994c8a01efdd3e9384c4c2.png

4、 关联对象相关方法-标记该对象是否有一些关联对象

a58b13f2718926dc1728be5e0c2365ff.png

5、 内存管理相关方法-我们平时使用的和内存相关的方法

1166638a029b032ded6f4e69edbe6f41.png

*注:详细的定义可以在Runtime源码编译后工程的Project Headers文件夹下,objc-private.h文件中查看关于objc_objc结构体的定义。

什么是objc_class

在OC语言中的Class对应的Runtime里objc_class, 下图为objc_class的定义,从图中我们也可以看出objc_class继承于objc_object,即objc_class中也含有一个isa指针,并且继承了objc_object的相关的方法及函数。所以我们定义的类也可以被看作是一个对象。

ca848daaa79644ad4138711e36daf921.png

截图中我们只截了重要的定义忽略了一系列的函数,如果想要查看,可以在Runtime源码编译后工程的Project Headers文件夹下objc-runtime-new.h中查看所有的方法。

而本文我们主要讲下最重要的三个数据成员。

1. Class superclass : Class类型,表示当前类的父类。

2. cache_t cache : 方法缓存的结构,在消息传递过程中会被用到。用于优化方法调用,提高性能。其数据结构实际上是一个可增量扩展的哈希表,用来缓存我们调用频次较高的函数。这个哈希表中存放的是bucket_t,而bucket_t中包含了key、IMP,key为方法名,而IMP我们可以将其理解为函数指针,这样在执行方法的时候我们拿到方法名就可以快速的查找到对应的执行函数指针。下图为cache_t及bucket_t的具体定义,同样可以在objc-runtime-new.h中找到。

23857df4532a235394cb49715a93a018.png
6175aa1c437ea343d0acc637b5b23a67.png

3. class_data_bits_t bits : 类结构中的核心部分,它的作用类似于优化过的isa指针,下文中会再详细。

class_data_bits_t bits

class_data_bits_t bits只含有一个成员uintptr_t bits,uintptr_t实际上是unsigned long类型,在arm64为8字节(64位),我们可以将uintptr_t bits理解为一个64位的存储域,里面存储的不仅包含指针,而且可以同时包含类的一些信息,这些信息通过对应的掩码获取,比如在类结构中非常重要的class_rw_t*就是通过(bits & FAST_DATA_MASK)来获取,具体见struct class_data_bits_t内部的data()函数。

9445fc13e3be32d272e0e9b40ea1d1e6.png

下面我们来看下class_rw_t是个什么呢?

class_rw_t定义

a42c09b592b5967a082f93e9d10f1e9a.png

截图中我们省略了函数,省略部分同样可以在objc-runtime-new.h中找到

从截图中我们可以看到最重要的数据结构有:

1、 class_ro_t *ro下面再分析这个数据结构。

2、 method_array_t method;方法列表。

3、 property_array_t properties;属性。

4、 protocol_array_t protocols;协议。

5、 firstSubclass、nextSiblingClass与继承相关的指针。

6、 demangledName Class对应的符号名称。

class_ro_t *ro常量指针

该指针指向的内容是只读不可修改的。关于class_ro_t的定义可以参见下图:

d05d2400a404b5bdec33fa74bca11006.png

需要我们关注的主要是:

* name 函数名

* baseMethodList 方法列表

* baseProtocols 协议

* ivars 类的成员变量

* baseProperties属性

其中method_list_t是一个数组包含了多个method_t,而method_t就是我们平常使用的函数,其结构体包括:

* 名称

* 返回值类型

* 函数体

* 参数如下图:

b522befb434319448d81a95cb464b645.png

总结:本文主要介绍了我们平常OC中使用的对象、类以及类中的方法在runtime中的定义及数据结构,关于runtime源码的编译可参见下边的Runtime源码编译链接。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值