34、以“自动释放池块”降低内存峰值

​ 系统会自动创建一些线程,如:主线程、GCD机制中的线程,这些线程默认都有自动释放池,每次执行“事件循环”(event loop)时,就会将其清空。

​ 如:man函数中的自动释放池:

int main(int argc, char *argv[]) {
  @autoreleasepool { // 如果不写,那么有UIApplicationMain函数所自动释放的对象,就没有自动释放池可以容纳,系统就会发出警告来表明
    return UIApplicationMain(argc, argv, nil, @"XXXAppdelegate");
  }
}

​ 如:需要从数据库中读出许多对象

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

Person的初始化函数也许会像上例那样,再创建出一些临时对象。若记录有很多条,则内存中也会有很多不必要的临时对象,它们本来应该提早回收的。此时增加一个自动释放池即可解决此问题。(及:解开注释部分)

​ 然而是否应该用池来优化效率,完全取决于具体的应用程序。首先的监控内存用量,判断其中有没有需要解决的问题,如果没有完成这一步,那就别记者优化。尽管自动释放池的开销不太大,但毕竟还是有的,所以尽量不要建立额外的自动释放池。

@autoreleasepool语法还有一个好处:每个自动释放池均有其范围,可以避免无意间误用了那些在清空池后已被系统回收的对象。

要点:

  • 自动释放池排布在栈中,对象收到·消息后,系统将其放入最顶端的池里

  • 合理运用自动释放池,可降低应用程序的内存峰值

  • @autoreleasepool这种新式写法能创建出更为轻便的自动释放池

Last updated

Was this helpful?