Runtime 面试题及详细答案(实战向)_第1页
Runtime 面试题及详细答案(实战向)_第2页
Runtime 面试题及详细答案(实战向)_第3页
Runtime 面试题及详细答案(实战向)_第4页
Runtime 面试题及详细答案(实战向)_第5页
已阅读5页,还剩2页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Runtime面试题及详细答案(实战向)整套题库聚焦iOS开发Runtime核心考点,剔除理论空话,答案贴合实际开发、面试话术,无生硬模板感,覆盖初级、中级开发高频面试场景。一、基础概念类(高频入门题)1.什么是Runtime?它的核心作用是什么?答案:Runtime是OC语言的一套底层运行时机制,本质是一套纯C语言编写的动态库,是OC面向对象、动态特性的底层支撑。OC代码在编译阶段只是做语法检查、代码翻译,不会确定方法的最终调用地址,所有的方法调用、对象创建、属性访问、消息转发都是在程序运行阶段,由Runtime动态完成。简单来说,编译期OC只是语法文本,运行期Runtime才让代码真正“活起来、跑起来”。2.谈谈OC的静态绑定和动态绑定,Runtime属于哪一种?答案:静态绑定:在编译阶段就确定方法的调用地址,程序运行时直接调用,效率高,C语言、Swift静态方法都是静态绑定。动态绑定:方法调用地址在运行时才动态确定,OC所有的对象方法调用都是动态绑定,完全依赖Runtime实现。Runtime是典型的动态绑定机制,这也是OC支持方法交换、动态添加方法、消息转发的核心原因。3.什么是消息机制?objc_msgSend做了什么?答案:OC中所有的[对象方法]调用,编译后都会被转换成底层的objc_msgSend函数调用,这就是Runtime的消息机制。objc_msgSend的核心执行流程:1.校验消息接收者(receiver),如果对象为nil,直接返回,不报错;2.从对象的类缓存中查找方法SEL和IMP对应关系,找到就直接执行方法实现;3.缓存中未找到,遍历类的方法列表查找;4.当前类未找到,沿着父类继承链逐级向上查找;5.最终未找到方法,进入消息转发流程,不会直接崩溃。二、核心数据结构类(中级必问)4.讲解Runtime中几个核心结构体:objc_object、objc_class、SEL、IMP答案:objc_object(对象结构体):所有OC对象的底层结构体,只有一个核心成员isa指针,指向对象所属的类。通过isa指针,对象才能找到自己的类、类的方法和属性。objc_class(类结构体):类的底层结构体,存储类的所有核心信息,包含isa(指向元类)、superclass(父类指针)、方法列表、属性列表、协议列表、缓存方法等。SEL(方法选择器):本质是方法名的字符串标识,编译后每个方法都会生成一个唯一的SEL,仅作为方法的唯一标识,不存储方法实现。不同类的同名方法,SEL是相同的。IMP(方法实现指针):本质是函数指针,指向方法的具体C语言实现地址。Runtime通过SEL匹配到对应的IMP,就能执行方法逻辑。5.什么是元类(meta-class)?元类的作用是什么?答案:实例对象的isa指向类,类的isa指向元类。元类是专门用来存储和管理类方法的特殊类。我们平时调用的实例方法,存储在普通类的方法列表中;类方法不属于实例,无法存储在普通类中,所以全部存储在元类的方法列表里。核心逻辑:1.调用实例方法:实例对象->类->查找实例方法;2.调用类方法:类->元类->查找类方法;3.所有元类的父类最终都是根元类,根元类的isa指向自己,形成闭环。6.isa指针的底层优化(TaggedPointer、非指针isa)答案:在旧版本OC中,isa就是单纯的指针,占用8字节,直接存储类的地址,内存占用大、效率低。现在的isa是优化后的联合体结构,不再是纯粹的指针,通过位域存储多种信息,充分利用内存空间:1.存储类的地址(核心);2.存储对象的引用计数、是否正在释放、是否是弱引用、是否有关联对象等标记位;3.TaggedPointer是针对小对象(NSNumber、NSString小文本)的优化,直接将数据存在isa指针中,不需要开辟堆内存,极大提升性能、减少内存占用。三、方法交换与动态操作(实战高频)7.什么是MethodSwizzle(方法交换)?原理和使用场景是什么?答案:MethodSwizzle是Runtime提供的动态方法交换能力,在程序运行时,交换两个方法的SEL和IMP对应关系,达到“调用原方法名,执行新方法逻辑”的效果。核心原理:每个类的方法列表中,SEL和IMP是一一绑定的,通过Runtime函数method_exchangeImplementations可以互换两个方法的IMP地址。常用实战场景:1.统一拦截系统方法,做全局逻辑处理(比如拦截UIButton点击、防止重复点击);2.全局日志统计(统计页面打开、按钮点击埋点);3.修复系统原生bug(系统私有方法异常、兼容机型适配问题);4.无侵入添加功能(给系统分类添加全局校验、容错处理)。8.方法交换有哪些坑?如何规避?答案:实战中方法交换的风险非常多,是面试重点:常见问题:1.多次交换导致方法逻辑错乱:多次执行交换代码,会让IMP来回互换,最终方法逻辑失效;2.父类子类方法交换冲突:子类交换父类方法,会影响父类及其他子类,引发未知bug;3.未调用原方法,丢失原有系统逻辑;4.分类加载顺序不确定,导致交换时机出错。规避方案:1.将方法交换写在+load方法中,保证类加载时只执行一次;2.增加静态标记,通过全局变量判断是否已经交换过,防止重复交换;3.交换后务必在新方法中调用原方法,保留原有逻辑;4.尽量只交换当前类的方法,不随意交换系统父类方法。9.+load和+initialize的区别?Runtime层面的执行逻辑?答案:两者都是类初始化相关的方法,但执行时机、次数、场景完全不同:+load1.类被加载到内存时立即执行,编译链接阶段触发;2.只会执行一次,父类、子类、分类都会独立执行;3.执行顺序:父类先于子类,主类先于分类;4.适合做方法交换、全局配置,不适合做耗时操作。+initialize1.类第一次被调用(实例化、调用类方法)时执行,懒加载机制;2.可能执行多次,子类未实现initialize时,会继承父类方法,导致父类重复调用;3.分类会覆盖主类的initialize方法;4.适合做类的全局初始化配置、静态数据初始化。四、消息转发机制(难点必问)10.OC调用未实现的方法为什么不会直接崩溃?讲解消息转发完整流程答案:OC依靠Runtime的三级消息转发机制,在方法未找到时层层补救,只有所有转发流程走完仍无实现,才会崩溃报unrecognizedselector错误。一级转发:动态方法解析Runtime发现方法未实现后,会先调用+resolveInstanceMethod:(实例方法)/+resolveClassMethod:(类方法),允许我们动态添加方法实现,补救缺失的方法。补救成功则正常执行,流程结束。二级转发:快速消息转发(备用接收者)一级解析失败后,调用-forwardingTargetForSelector:,可以返回一个其他对象,让这个备用对象处理当前方法。适合快速转发、多对象共用方法的场景,开销最小。三级转发:完整消息转发二级转发失败后,调用-methodSignatureForSelector:生成方法签名,再调用-forwardInvocation:,可以自定义消息处理逻辑、修改方法参数、转发给多个对象,是最灵活、开销最大的转发方式。三级转发全部失败后,最终调用-doesNotRecognizeSelector:,程序崩溃。11.消息转发的实际开发用途?答案:1.实现多代理模式,将一个方法转发给多个对象处理;2.实现类的解耦,不用继承、不用协议,即可复用其他类的方法;3.做方法容错,拦截未实现的方法,避免程序崩溃;4.实现类似消息分发、事件转发的逻辑,简化代码结构。五、属性与关联对象(实操考点)12.@property的底层实现原理?ivar、getter、setter逻辑答案:@property只是编译器声明,底层依靠Runtime自动生成三件套:成员变量(ivar)、getter方法、setter方法。1.成员变量ivar:存储属性的真实数据,默认带下划线;2.setter方法:根据属性修饰符(strong/copy/weak)完成赋值、内存操作;3.getter方法:读取成员变量的值。不同修饰符底层逻辑:-strong:赋值时持有对象,引用计数+1;-copy:深拷贝对象,生成新内存,打破原对象内存关联;-weak:不持有对象,仅存储地址,对象销毁后自动置空,依靠Runtime维护弱引用表。13.分类为什么不能添加属性?如何解决?答案:分类的底层结构体中,只有方法列表、协议列表,没有成员变量列表。所以直接在分类写@property,只会生成方法声明,不会生成ivar成员变量和方法实现,无法存储数据。解决方案:Runtime关联对象通过objc_setAssociatedObject和objc_getAssociatedObject动态给分类对象绑定额外数据,模拟属性存储。关联对象不是存储在对象自身内存中,而是存储在Runtime的全局关联哈希表中,对象销毁时,Runtime会自动移除对应的关联数据。六、内存与底层原理(进阶面试题)14.Runtime如何管理弱引用(weak原理)?答案:1.当给一个变量修饰weak时,Runtime会将该变量的地址,存入全局弱引用表中;2.当对象的引用计数为0、即将销毁时,Runtime会遍历弱引用表,找到所有指向该对象的weak变量;3.自动将所有weak变量置为nil,避免野指针崩溃;4.弱引用表是哈希结构,查询、修改效率极高,不会影响性能。15.讲讲Runtime的方法缓存机制,为什么能提升调用效率?答案:如果每次调用方法都遍历类、父类的方法列表,递归查找效率极低。所以Runtime为每个类维护了一个方法缓存cache。1.当一个方法第一次被调用时,Runtime查找完IMP后,会将SEL和IMP的对应关系存入缓存;2.后续再次调用该方法,直接从缓存中取值,无需遍历继承链;3.缓存采用哈希表结构,读写速度极快,是OC方法调用高效的核心原因。七、综合实战面试题(压轴题)16.用Runtime实现一个简单的字典转模型,核心思路是什么?答案:核心就是利用Runtime动态获取类的所有属性,遍历字典自动赋值,无需手动写赋值代码。核心步骤:1.通过class_copyIvarList获取当前类的所有成员变量ivar;2.遍历ivar列表,获取每个属性的名称;3.根据属性名称从字典中取出对应value;4.通过object_setIvar动态给模型对象赋值;5.兼容字典ke

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论