iOS 底层探索:OC底层面试题分析(会持续补充)

iOS 底层探索: 学习大纲 OC篇

前言

  • 探索了一阵子的OC底层原理之后,我们通过下面几个面试题复习一下。

目录

    1. Runtime是什么?
    1. 方法的本质,sel是什么?IMP是什么?两者之间的关系又是什么?
    1. 方法的调用顺序
    1. Runtime是如何实现weak的,为什么可以自动置nil
    1. 能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量
    1. Runtime Asssociate方法关联的对象,需要在dealloc中释放?
    1. [self class]和[super class]的区别?
    1. 内存平移问题

一、Runtime是什么?

  • runtime是由C和C++汇编实现的一套API,为OC语言加入了 面向对象、以及运行时的功能
  • 平时编写的OC代码,在程序运行的过程中,其实最终会转换成runtime的C语言代码, runtime是OC的幕后工作者
  • 运行时是指将数据类型的确定由编译时 推迟到了 运行时

举例:category分类,添加属性是无用的,调用属性会crash,但是通过runtime动态关联对象,重写setter、getter方法的方式就可以实现分类的属性。

二、方法的本质,sel是什么?IMP是什么?两者之间的关系又是什么?

  • 方法的本质:发送消息,消息会有以下几个流程

    • 快速查找(objc_msgSend) - cache_t缓存消息中查找

    • 慢速查找 - 递归自己|父类 - lookUpImpOrForward

    • 查找不到消息:动态方法解析 - resolveInstanceMethod

    • 消息快速转发 - forwardingTargetForSelector

    • 消息慢速转发 - methodSignatureForSelector & forwardInvocation

  • sel是方法编号 - 在read_images期间就编译进了内存 ,sel 相当于 一本书的目录title

  • imp是函数实现指针 ,找imp就是找函数的过程 ,imp 相当于 书本的页码

  • 查找具体的函数就是想看这本书具体篇章的内容

    • 1、首先知道想看什么,即目录 title - sel
    • 2、根据目录找到对应的页码 - imp
    • 3、通过页码去翻到具体的内容

三、方法的调用顺序

类的方法 和 分类方法 重名,如果调用,是什么情况?

  • 如果同名方法是普通方法,包括initialize -- 先调用分类方法

    • 因为分类的方法是在类realize之后 attach进去的,插在类的方法的前面,所以优先调用分类的方法(注意:不是分类覆盖主类!!)
    • initialize方法什么时候调用? initialize方法也是主动调用,即第一次消息时调用,为了不影响整个load,可以将需要提前加载的数据写到initialize中
  • 如果同名方法是load方法 -- 先 主类load,后分类load(分类之间,看编译的顺序)

四、 Runtime是如何实现weak的,为什么可以自动置nil

  • 初步回答:
    runtime 对注册的类会进行布局,对于 weak 修饰的对象会放入一个 hash 表(弱引用表)中。 用 weak 指向的对象内存地址作为key,当此对象的引用计数为0的时候会 dealloc,假如 weak 指向的对象内存地址是a,那么就会以a为键, 在这个 weak表中搜索,找到所有以a为键的 weak 对象,从而设置为 nil。

  • 细致回答:

    • 1.初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。
    • 2.添加引用时:objc_initWeak函数会调用objc_storeWeak() 函数, objc_storeWeak()的作用是更新指针指向,创建对应的弱引用表。
    • 3.释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak 指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。

当weak引用指向的对象被释放时,如何去处理weak指针?

1、调用objc_release
2、因为对象的引用计数为0,所以执行dealloc
3、在dealloc中,调用了_objc_rootDealloc函数
4、在_objc_rootDealloc中,调用了object_dispose函数
5、调用objc_destructInstance
6、最后调用objc_clear_deallocating

简单来说:
a. 从weak表中获取被释放对象的地址为键值的记录
b. 将包含在记录中的所有附有 weak修饰符变量的地址,赋值为 nil
c. 将weak表中该记录删除
d. 从引用计数表中删除废弃对象的地址为键值的记录

五、能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?

  • 问题一: 不可以。 因为编译好的实例变量存放的位置在ro,一旦编译完成,内存结构就完全确定了,无法修改。
  • 问题二:在register注册前,可以添加。但是调用运行时register注册后,就完成了内存的注入,内存结构确定了,无法修改。

六、Runtime Asssociate方法关联的对象,需要在dealloc中释放?

  • 不会,因为在dealloc中会自动释放掉关联的对象,在关联对象的时候,isa中记录了是否有关联对象。通过dealloc 释放。执行如下:objc_object::rootDealloc() -> object_dispose()->objc_destructInstance() ,在objc_destructInstance() 这里面会根据isa指针下的has_assoc标记来判断是否有关联对象,如果有会自动释放的。

七、 [self class]和[super class]的区别?

  • 主要是他们方法查找顺序不一样。[super class]中,其中super 是语法的 关键字,可以通过clang 看super的本质,这是编译时的底层源码,其中第一个参数是消息接收者,是一个__rw_objc_super结构
  • [self class]就是发送消息 objc_msgSend,消息接收者是self,方法编号 class
  • [super class] 本质就是objc_msgSendSuper,消息的接收者还是 self,方法编号 class,在运行时,底层调用的是_objc_msgSendSuper2
  • 实际运行时,[super class]在汇编层执行直接从superclass父类开始搜索,节约了一轮查找资源, objc_msgSendSuper2 会更快,直接跳过self的查找
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容