autorelease的对象与@autoreleasepool

本文探讨了@autoreleasepool的使用场景和autorelease对象的释放时机。通过代码示例,展示了在循环中未使用@autoreleasepool导致的内存问题,以及如何平衡内存管理和性能。Apple文档建议在命令行程序、包含大量临时对象的循环、新线程创建或长时间后台任务中使用@autoreleasepool。
摘要由CSDN通过智能技术生成

首先,看两段代码执行之后,内存的变化:

1、
// 未使用@autoreleasepool
for (int i = 0; i < 100000; i ++) {
        UIImage *img = [UIImage imageNamed:@"test.jpg"];
        NSLog(@"%@", @(i));
    }

分析:imageName 返回的是 autorelease 的对象,因为我们一直处在循环中,因此它们将一直没有机会被释放。如果数量太多而且数据太大的时候,很容易因为内存不足而崩溃。若 for 循环中为 非autorelease 的对象,不会出现内存问题。
如下图,我们可以看到内存占用情况:
在这里插入图片描述

2、
// 使用@autoreleasepool
for (int i = 0; i < 100000; i ++) {
        @autoreleasepool {
            UIImage *img = [UIImage imageNamed:@"test.jpg"];
            NSLog(@"%@", @(i));
        }
    }

分析:这就涉及到 autorelease 的对象在什么时候释放的问题。
引用【在没有手加Autorelease Pool的情况下,Autorelease对象是在当前的runloop迭代结束时释放的,而它能够释放的原因是系统在每个runloop迭代中都加入了自动释放池Push和Pop】。对于我们手动添加的@autoreleasepol{},显然出了它的作用域之后对象就会被release。这里我们每一次循环都生成了一个自动释放池,虽然可以保证内存使用达到最小,但是释放过于频繁也会带来潜在的性能忧虑。一个折中的方法是将循环分隔开加入自动释放池,比如每10次循环对应一次自动释放,这样能减少带来的性能损失。
如下图,内存占用情况:
在这里插入图片描述

什么时候用@autoreleasepool

根据Apple的文档,使用场景如下:

  1. 写基于命令行的的程序时,就是没有UI框架,如AppKit等Cocoa框架时。
  2. 写循环,循环里面包含了大量临时创建的对象。(本文的例子)
  3. 创建了新的线程。(非Cocoa程序创建线程时才需要)
  4. 长时间在后台运行的任务。
注:

1、什么是autorelease 的对象?
alloc、new、copy、mutableCopy四个内存管理的关键字,自身使用了这些关键字产生的对象都不是 autorelease 的对象,自身持有对象,那么不再需要时对象就会调用release方法释放对象;
不是通过上面关键字产生的都是 autorelease 的对象,底层会将该对象注册到 autoreleasepool 中,不会立即释放,会在pool结束时,释放对象。
2、参考
iOS内存管理
黑幕背后的Autorelease
@autoreleasepool-内存的分配与释放

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值