iOS探索:Runtime之基本数据结构

objc_object

国际惯例,流程图

WX20181211-150059@2x.png

  • 首先平时我们所使用的对象都是id类型的,id对应到runtime中就是objc_object这样的一个结构体,在这个结构体当中主要包含以下几个部分:
    1、第一部分是isa_t,实际上呢isa_t是一个共用体
    2、在objc_object中还包含了关于isa操作相关的方法,比如说通过objc_object这个结构体来获取isa所指向的类对象,通过类对象的isa指针获取它的元类对象
    3、还包含了一些弱引用相关的一些方法,比如说标记一个对象它是否有过弱引用指针
    4、还有关于关联对象的一些方法,比如说为一个对象我们设置一些关联属性,关于关联属性的一些方法也体现在objc_object这个结构体中
    5、最后还包括内存管理相关的一些方法,比如说我们再MRC下经常使用到的retain和relese方法,包括MRC和ARC下面都可以用到的autorelesepool(自动释放池),这些关于内存管理相关的方法都是封装在objc_object这个结构体中

objc_class

WX20181211-151829@2x.png
  • 我们在OC语言中所使用的Class,代表的是一个类,在runtime中对应的是objc_class这样一个结构体,它继承自objc_object,那么问题来了:Class这样一个类,它是否是一个对象呢?答案当然是肯定的,我们称之为类对象,因为它继承自objc_object

  • 在objc_class这个结构体中,包含superClass这样一个指针,它指向的也是一个Class,例如:如果这个Class是一个类对象,那么它的superClass指针指向的事它的父类对象,一个类对象与它的父类对象也正是通过这个superClass指针来建立起联系

  • 接下来它还包含一个cache_t这样一个成员变量,cache_t它表达了方法缓存的一个结构,我们在进行消息传递的时候会使用到对于方法缓存的这样一个数据结构

  • 第三个是关于class_data_bits_t这样的一个数据结构,实际上我们对于一个类所定义的变量,属性,包括它的一些方法都在bits这样一个数据结构当中

isa指针

共用体isa_t

WX20181211-153729@2x.png
  • isa的结构主要是C++中的共用体,我们在OC当中实际上是定义成了一个isa_t这样一个名称,对于一个共用体来说,不论它是在64位架构还是在32位架构上面,它实际上都是32个0或者1的数字(或者64个0或者1的数字)

  • isa指针主要分为两种:一种是指针型isa,另一种是非指针型isa

  • 指针型isa:isa的值代表的是Class的地址,也就是64个(或者32,看架构)0或者1它的整体内容所代表的是所指向的Class的地址

  • 非指针型isa:isa的值的部分代表的是Class的地址,比如说针对64位架构来说,可能对应的是某一部分33位或者44位所代表的值,并不是整个64位都代表,这样做的一个目的是我们在寻址过程中只有三四十位的位数就可以保证我们找到所有Class的地址,多出来的这些位可以用来保存其他的内容,达到节省内存的目的

isa的指向

  • 关于对象,isa指向的是其类对象

  • 关于类对象,isa指向的是其元类对象

cache_t

  • 用于快速查找方法执行函数 例如我们在调用一个方法的时候,如果这个方法已经缓存,我们就不用去其对应的方法列表中遍历查找,从而节省时间

  • 可增量扩展的哈希表结构 增量扩展体现在当我们这个结构存储量在扩大的时候会它也会逐渐的扩大它的内存结构用哈希表来实现也是为了提高查找效率

  • 局部性原理的最佳应用 例如我们在调用方法的时候,其实每次调用的都是某几个方法,如果把这些调用频率较高的方法放到方法缓存中,那么下次调用的命中就会更高

WX20181211-160428@2x.png
  • cache_t其实可以理解为一个数组来实现的,数组当中都是bucket_t这样的一个结构体来封装的

  • 对于bucket_t它有两个重要的成员变量,一个是key,一个是IMP,对于key实际上是OC语言中的selector,在调用一个方法的时候它实际上是一个选择器SEL,对应的就是这里面的key,我们可以通过一个方法选择器的名称来寻找一个方法的具体实现。IMP我们可以理解为一个无类型的函数指针

  • 比如说现在我们拿到一个key,我们可以通过哈希查找算法来定位当前这个key所对应的bucket_t这个结构体位于数组中的哪个位置,我们定位到这个位置后我们就可以提取其中的IMP指针指向的具体函数实现来调用这个函数

class_data_bits_t

  • class_data_bits_t主要是对class_rw_t的封装

  • class_rw_t代表了类相关的读写信息(比如说我们给类添加的分类中的一些方法,或者属性以及协议)、对class_ro_t的封装

  • class_ro_t代表了类相关的只读信息

class_rw_t

WX20181211-162348@2x.png
  • class_rw_t主要包含class_ro_t、protocols(协议)、properties(属性)、methods(方法列表),对于协议,属性和方法列表的数据结构是二维数组

class_ro_t

WX20181211-163241@2x.png
  • class_ro_t主要包含name(名字)、ivars(成员变量)、protocols(协议)、properties(属性)、methodList(方法列表),对于成员变量、协议、属性和方法列表的数据结构是一维数组,与class_rw_t的区别在:在class_rw_t中一般存放的是分类的一些内容,而在class_ro_t中一般存放类原始的一些内容和信息(个人理解)

method_t

WX20181211-164853@2x.png
  • method_t是一个结构体类型,主要包括SEL类型的name(方法的名称)、types(对应的是函数的返回值和参数的组合)、IMP类型的imp(无类型的函数指针,对应函数体)

Type Encodings

WX20181211-165508@2x.png
  • const char* types是一个不可变得字符指针,它的组成结构如上图所示,首先第一位是返回值,后面是参数,为啥第一位置是返回值呢?因为我们定义一个函数的时候,函数的参数可以有多个,但是返回值只能有一个,如果没有返回值,那么返回值的类型可以用void来修饰,所以返回值占据types中的第一个位置

  • 举个栗子,例如在OC中- (void)aMethod;这个方法,它的返回值是void类型的,没有参数,它对应的types就是v@:

  • 首先v对应的事返回值(void类型),@对应的是参数1(id类型),:对应的事参数2(SEL),这个解释一下:当我们调用一个方法或者说是方法消息传递时到runtime层面会转化成调用objc_msgSend方法,这个函数中的第一个参数和第二个参数是不可变的(固定的),第一个参数必须是id类型的,及消息的接受者(self),第二个参数表示是一个选择器,所以用这样一个字符串来表示

整体数据结构

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

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,678评论 0 9
  • Objective-C语言是一门动态语言,他将很多静态语言在编译和链接时期做的事情放到了运行时来处理。这种动态语言...
    tigger丨阅读 1,378评论 0 8
  • 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的...
    西木阅读 30,537评论 33 466
  • 原文出处:南峰子的技术博客 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了...
    _烩面_阅读 1,214评论 1 5
  • Sailing333阅读 154评论 0 0