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?