面试题答案
一键面试在多线程编程中使用 @autoreleasepool
的特殊表现及注意点
- 自动释放池的生命周期:在多线程环境下,每个线程都有自己独立的自动释放池栈。主线程有默认的自动释放池,会在每次运行循环迭代结束时排空。但对于子线程,如果不手动创建
@autoreleasepool
,自动释放对象会一直累积,直到线程结束才释放,可能导致内存峰值过高。 - 内存管理时机:在子线程中适时创建
@autoreleasepool
可以及时释放临时对象占用的内存,避免内存占用持续增长。
实际场景举例及正确使用方式
假设我们在一个子线程中进行大量图片处理任务,每张图片处理后会生成临时的图像数据对象。这些对象如果不及时释放,会占用大量内存。
// 创建一个新线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 创建自动释放池
@autoreleasepool {
for (int i = 0; i < 1000; i++) {
// 模拟图片处理生成临时对象
UIImage *image = [UIImage imageNamed:@"example.jpg"];
// 对图片进行处理,比如缩放等操作
// 处理完成后,image 会在自动释放池排空时释放
}
}
// 自动释放池结束,临时对象被释放,避免了内存累积
});
通过在子线程中创建 @autoreleasepool
,可以确保在每次循环结束时,处理图片生成的临时 UIImage
对象能及时被释放,从而有效控制内存增长,避免内存问题。