美文网首页
第34条:以“自动释放池”降低内存峰值

第34条:以“自动释放池”降低内存峰值

作者: MrSYLong | 来源:发表于2018-10-14 16:12 被阅读6次

    Objective-C对象的生命周期取决于其引用计数。

    释放对象有两种方式:

    • 调用release方法,使其保留计数立即递减
    • 调用autorelease方法,将其加入”自动释放池“中。自动释放池用于存放那些需要在稍后某个时刻释放的对象。清空自动释放池时,系统会向其中的对象发送release消息。
    // 创建自动释放池
    @autoreleasepool{
           
      }
        
    注意:花括号定义了自动释放池的范围。自动释放池于左花括号处创建,并于对应的右花括号处自动清空。
    位于自动释放池范围内的对象,将在此范围末尾处收到release消息。
    

    在执行循环体时,一般会持续有新对象创建出来,并加入自动释放池中。这种对象都要等到循环执行完才会释放。这样一来,在执行循环时,应用程序所占内存量会持续上涨,而等到所有临时对象都释放后,内存用量又会突然下降。

    NSArray *databaseRecords = /* ... */;
    NSMutableArray *people = [NSMutableArray new];
    for(NSDictionary *record in databaseRecords){
        EOCPerson *person = [[EOCPerson alloc] initWithRecord:record];
        [people addObject:person];
    }
    

    这种情况不甚理想,尤其是循环长度无法预知时,再创建出一些临时的EOCPerson对象,它们本该提早回收的。增加一个自动释放池即可解决问题,把循环内的代码包裹在自动释放池块中,那么循环体中自动释放的对象就会在这个池,而不是线程的主池里:

    NSArray *databaseRecords = /* ... */;
    NSMutableArray *people = [NSMutableArray new];
    for(NSDictionary *record in databaseRecords){
        @autoreleasepool{
            EOCPerson *person = [[EOCPerson alloc] initWithRecord:record];
            [people addObject:person];
        }
    }
    

    加上自动释放池之后,就会降低应用程序在执行循环时的内存峰值。因为系统会在块的末尾将临时对象回收掉。如果循环的内存用量不高,则尽量不建立额外的自动释放池,因为自动释放池块还是存在开销(虽然不大)。

    在ARC出现之前一般使用NSAutoreleasePool对象,这样可以不用每次循环都清空池,通常用来创建偶尔需要清空的池:

    NSArray *databaseRecords = /* ... */;
    NSMutableArray *people = [NSMutableArray new];
    int i = 0;
    
    // 创建自动释放池会被推入栈中,在对象上执行autorelease等于将其放到栈顶的自动释放池中。
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    for(NSDictionary *record in databaseRecords){
        EOCPerson *person = [[EOCPerson alloc] initWithRecord:record];
        [people addObject:person];
    
        // 每执行10次循环,清空一次自动释放池
        if (++i == 10){
            [pool drain];
            i = 0;;
        }
    }
    // 结束循环后,再次清空自动释放池
    [pool drain];
    

    相关文章

      网友评论

          本文标题:第34条:以“自动释放池”降低内存峰值

          本文链接:https://www.haomeiwen.com/subject/rqttzftx.html