面试题答案
一键面试自动释放池的工作原理
-
何时创建:
- 在iOS应用程序启动时,系统会自动创建一个全局的自动释放池,这个自动释放池会在应用程序的主线程运行循环的每次迭代中被自动创建和销毁。
- 开发者也可以手动创建自动释放池,使用
@autoreleasepool
块。例如:
@autoreleasepool { // 代码块内创建的对象会被加入到这个自动释放池中 }
-
何时销毁:
- 对于系统自动创建的主线程自动释放池,它会在主线程运行循环的每次迭代结束时被销毁。也就是说,在处理完一次事件循环中的所有任务后,这个自动释放池会被销毁,池中的对象会收到
release
消息。 - 手动创建的
@autoreleasepool
块,当程序执行到块的末尾时,自动释放池会被销毁,其中的对象也会收到release
消息。
- 对于系统自动创建的主线程自动释放池,它会在主线程运行循环的每次迭代结束时被销毁。也就是说,在处理完一次事件循环中的所有任务后,这个自动释放池会被销毁,池中的对象会收到
-
对象加入自动释放池的过程:
- 当一个对象发送
autorelease
消息时,它会被添加到最近的自动释放池中。 - 在Objective - C运行时,每个线程都有自己的自动释放池栈。当一个对象调用
autorelease
,运行时系统会将这个对象添加到当前线程自动释放池栈顶部的自动释放池中。例如:
NSObject *obj = [[NSObject alloc] init]; [obj autorelease]; // obj被添加到最近的自动释放池中
- 当一个对象发送
自动释放池对对象内存布局在运行时的影响
-
内存占用:
- 自动释放池本身会占用一定的内存空间,用于管理其中的对象列表。不过,这个内存开销相对较小。
- 对于加入自动释放池的对象,它们在内存中的布局并不会因为加入自动释放池而改变。对象仍然按照其自身的结构和属性分配内存。但是,由于对象在自动释放池中等待释放,会在一定时间内占用额外的内存,直到自动释放池销毁并向对象发送
release
消息。如果在自动释放池中创建了大量临时对象,可能会导致内存峰值升高。
-
释放时机:
- 自动释放池改变了对象的释放时机。如果没有自动释放池,对象在发送
release
消息后,引用计数减为0就会立即释放。而加入自动释放池后,对象要等到自动释放池销毁时才会收到release
消息。这意味着对象的生命周期会延长到自动释放池销毁之时。例如,在一个循环中创建大量临时对象并调用autorelease
,如果没有及时销毁自动释放池,这些对象会一直占用内存,直到包含它们的自动释放池销毁。合理使用自动释放池,可以控制对象的释放时机,避免内存峰值过高,提高程序的内存使用效率。
- 自动释放池改变了对象的释放时机。如果没有自动释放池,对象在发送