MST
星途 面试题库

面试题:Objective-C中__block与__weak关键字对ARC机制的影响及底层实现细节

在ARC(自动引用计数)环境下,__block与__weak关键字是如何与ARC机制协同工作的?请深入阐述它们的底层实现原理,包括但不限于对象的引用计数变化、runtime层的操作以及编译器所做的优化。
34.5万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

__block关键字与ARC机制协同工作及原理

  1. 对象引用计数变化:在ARC环境下,使用__block修饰的变量,如果其类型是对象类型,它会对对象进行强引用。当__block变量指向对象时,对象的引用计数会增加。例如:
__block NSObject *obj = [[NSObject alloc] init]; 
// 此时obj对NSObject对象有强引用,对象引用计数加1

__block变量生命周期结束或者重新赋值为nil时,对象引用计数会相应减少。 2. runtime层操作:在runtime层,__block变量会被包装成一个结构体。这个结构体内部会包含指向所引用对象的指针。当在block内部访问__block变量时,实际上是通过这个结构体来访问的。例如,当block捕获__block变量时,runtime会处理结构体的内存管理,确保在block执行期间,__block变量所引用的对象不会被提前释放。 3. 编译器优化:编译器会对__block变量的访问进行优化。在编译期,编译器会生成特定的代码来处理__block变量的引用和释放逻辑。例如,在block内部对__block变量的赋值操作,编译器会生成代码来正确调整对象的引用计数。同时,编译器会确保__block变量在不同作用域之间的传递和使用是符合内存管理规则的。

__weak关键字与ARC机制协同工作及原理

  1. 对象引用计数变化__weak关键字用于创建一个弱引用。弱引用不会增加对象的引用计数。例如:
NSObject *strongObj = [[NSObject alloc] init];
__weak NSObject *weakObj = strongObj; 
// weakObj对strongObj所指向的对象没有增加引用计数

当对象的强引用计数降为0并被释放时,所有指向该对象的__weak指针会自动被设置为nil,即所谓的“零弱引用”特性。 2. runtime层操作:runtime维护了一个弱引用表,用于记录所有的弱引用关系。当对象即将被释放时,runtime会遍历这个弱引用表,将所有指向该对象的__weak指针置为nil。这个过程涉及到runtime对对象生命周期的监控以及对弱引用表的操作。例如,当对象的引用计数变为0时,runtime会调用objc_destructInstance函数,在这个函数中会处理弱引用的归零操作。 3. 编译器优化:编译器在处理__weak变量时,会生成代码来确保在使用__weak变量时,首先检查其是否为nil,以避免野指针访问。同时,编译器会协助runtime正确地管理弱引用关系,例如在对象的内存布局中预留空间来存储弱引用信息,以便runtime能够高效地处理弱引用的添加和移除操作。