关于ZAKER 融媒体解决方案 合作 加入

iOS 消息调用过程面试题(头条)

CocoaChina 11-19

iOS 消息调用过程面试题(头条)

码出未来 _9102 · 2019-11-19 阅读数 27

iOS 消息调用属于基本知识,苹果官方有一个详细的介绍图:

iOS 工程中,调用对象的方法,就是向对象发送消息。我们知道,iOS 中的方法分为实例方法和对象方法。iOS 所有的对象都是继承至 NSObject, 编译完成后,在对象的定义中,存在一个实例方法链表、一个缓存方法链表。当对实例 son 发送消息后,会在 son 缓存方法链表中寻找;缓存中没有时,向实例方法链表寻找;再找不到,会向父类的实例方法缓存链表 -> 父类的实例方法链表寻找,直至 NSObject。在 NSObject 中会经历以下两个步骤:

1 - ( BOOL ) resolveInstanceMethod: ( SEL ) sel ; 2 - ( id ) forwardingTargetForSelector: ( SEL ) aSelector ;

如果在步骤 2 中范围 nil, 就会触发 iOS 的崩溃。当向 Son 发送类方法时,会首先向 Son 的元类 metaClass 中的类缓存方法链表中寻找,然后类方法链表,然后直接在 NSObject 进行缓存方法链表 -> 类方法链表的寻找路径 . 在 NSObject 中会经历如下两个步骤:

实例的 methodList 链表中寻找方法,找不到时会寻找 Son 的类方法,仍然找不到时,会寻找父类的方法链表,直到 NSObject 。

其中不同对象间的切换,通过 isa 指针完成,实例 son 的 isa 指向类 Son, 类 Son 的 isa 指向元类,元类的 isa 指向父类的元类, 父类的元类向上传递,直至 NSObject .

NSObject 的指针 isa 指向其本身,在想 NSObject 发送消息时,会经历如下步骤:

1 + ( BOOL ) resolveClassMethod: ( SEL ) sel ; 2 - ( void ) doesNotRecognizeSelector: ( SEL ) aSelector ;

当调用方法 2 时,会触发 iOS 的崩溃。利用以上机制,可以对 resolveInstanceMethod 和 resolveClassMethod 两个方法进行方法交换,拦截可能出现的 iOS 崩溃,然后自定义处理。

推荐文章:iOS 面试题 答案合集

以上内容由"CocoaChina"上传发布 查看原文

觉得文章不错,微信扫描分享好友

扫码分享