面试题答案
一键面试ARC 和 MRC 在 Objective - C 内存管理中的主要差异
- 内存管理方式:
- MRC(手动引用计数):开发者需要手动调用
retain
、release
和autorelease
方法来管理对象的引用计数。例如,当创建一个对象时,它的引用计数通常为 1,如果需要保持对象不被释放,要调用retain
使引用计数加 1;当不再需要对象时,调用release
使引用计数减 1,当引用计数为 0 时,对象的内存被释放。 - ARC(自动引用计数):ARC 由编译器自动插入引用计数相关的代码。开发者不再需要手动调用
retain
、release
和autorelease
方法,编译器会在适当的位置自动添加这些代码来管理对象的生命周期。
- MRC(手动引用计数):开发者需要手动调用
- 内存管理的准确性和效率:
- MRC:手动管理引用计数容易出错,例如过度释放对象(双重释放)或忘记释放对象导致内存泄漏。而且开发者需要花费更多精力来确保引用计数操作的准确性。
- ARC:ARC 大大减少了手动内存管理的错误,提高了代码的安全性和稳定性。编译器根据对象的作用域等信息,精确地插入引用计数操作代码,提高了内存管理的效率。
- 代码可读性和维护性:
- MRC:手动引用计数操作会使代码中充斥着大量与内存管理相关的代码,降低了代码的可读性和维护性。
- ARC:代码中不再有手动引用计数的代码,使代码更加简洁,提高了代码的可读性和可维护性。
从 MRC 转换到 ARC 可能遇到的潜在问题及解决方法
- 手动内存管理代码残留问题:
- 问题:项目中可能存在手动调用
retain
、release
、autorelease
等方法的代码,在 ARC 模式下这些代码会导致编译错误。 - 解决方法:删除所有手动引用计数相关的代码,ARC 会自动插入相应的内存管理代码。可以使用 Xcode 的“Convert to Objective - C ARC”功能,该功能会自动帮开发者移除大部分手动引用计数代码,但仍需手动检查和修正一些复杂情况,比如在
dealloc
方法中释放资源的代码,需要将其迁移到@property
的didSet
和willSet
方法中或其他合适的位置。
- 问题:项目中可能存在手动调用
- Core Foundation 桥接问题:
- 问题:在 MRC 中,开发者负责管理 Core Foundation 对象(如
CFStringRef
、CFArrayRef
等)的内存,使用CFRetain
和CFRelease
等函数。在 ARC 下,Core Foundation 和 Objective - C 对象之间的桥接需要特别注意,因为 ARC 不能自动管理 Core Foundation 对象的引用计数。 - 解决方法:使用
__bridge
、__bridge_retained
和__bridge_transfer
等关键字进行 Core Foundation 和 Objective - C 对象之间的桥接。__bridge
表示不改变对象的所有权,__bridge_retained
表示将 Core Foundation 对象的所有权转移给 ARC 管理的 Objective - C 对象,__bridge_transfer
表示将 ARC 管理的 Objective - C 对象的所有权转移给 Core Foundation 对象。
- 问题:在 MRC 中,开发者负责管理 Core Foundation 对象(如
- 与第三方库的兼容性问题:
- 问题:项目中使用的第三方库可能不支持 ARC,在转换项目到 ARC 时会导致编译错误。
- 解决方法:对于不支持 ARC 的第三方库,有两种解决方式。一是对第三方库的代码进行修改,使其支持 ARC;二是在项目的 Build Phases 中,针对该第三方库的源文件,在“Compile Sources”中添加
-fno -objc -arc
编译标志,告诉编译器对这些文件不使用 ARC 进行编译。
- dealloc 方法中的资源释放问题:
- 问题:在 MRC 中,
dealloc
方法用于释放对象持有的资源(如释放malloc
分配的内存、关闭文件描述符等)并调用[super dealloc]
。在 ARC 下,dealloc
方法中不能调用[super dealloc]
,并且对象的引用计数相关的内存释放由 ARC 自动管理,开发者只需关注手动分配的资源释放。 - 解决方法:将
dealloc
方法中释放引用计数管理的对象的代码移除,只保留手动分配资源(如malloc
分配的内存)的释放代码。对于@property
属性,如果需要在对象销毁前做一些处理,可以使用didSet
和willSet
方法来代替在dealloc
中进行操作。
- 问题:在 MRC 中,