Advanced Autorelease Pool 高级自动释放池
在之前的章节你已经学习了很多基本的内存方面的知识。这个部分将会涉及到使用自动释放的高级技术,同时展示你应该在哪里使用,从而在受限的情况下获得比较高的性能。
在每一个线程中,你应该要有一个自动释放池来收集和存储所有自动释放的对象。如果在每一个线程中,没有自动释放池的话,所有的autoreleased对象会泄露,你将会有一个重大的内存泄露。自动释放池是通过栈的形式组织在一起的;下面部分会解释。
自动释放池和栈
自动释放池存储在一个栈中,通常被理解成嵌套的。无论何时你创建一个新的自动释放池,它都会被push到栈的顶部。然后所有新的autoreleased对象会被push到这个新的自动释放池中。
通过下面的代码你可以看到,对象(比如myArray和myString)内部的方法doSomething将会存储在myPool中,而不是应用的main pool中:
- (void)doSomething {
@autoreleasepool {
NSArray *myArray = [NSArray array];
NSString *myString = [NSString string];
}
}
这是main方法的main pool:
int main(int argc, char *argv[]){
@autoreleasepool {
int retVal = UIApplicationMain(argc, argv, nil, nil);
}
return retVal;
}
在@autoreleasepool块结束的时候,当时间生命周期结束时,所有存储在这个pool中的autoreleased对象jiang将被released。
图7-9展示了这个概念。对于一个好的性能来说,这是一个非常重要的概念 -- 知道尽可能快的release对象。
自动释放池和线程
当创建一个新的线程时,你需要创建一个新的自动释放池对象,然后将这个pool和新的线程联系在一起。因此当线程停止时,你的自动释放池会deallocated,所有的autoreleased对象也会deallocated。第6章我会深入的讨论这个主题,所以你应该复习一下,如果你在理解概念时需要一些帮助的话。
自动释放池对性能的影响
旧的内存管理规则依然能够应用在用ARC编写的代码上,如果你没有使用new,alloc和copy调用一个方法,这个对象就已经是autoreleased了。如果你在一个循环中创建了很多的autoreleased对象,很快内存就会耗尽。
这个代码演示了在循环中处理内存管理最好的方法:
- (void)doSomethingWithAutoRelease {
for (int i = 0; i < 1000; i++) {
@autoreleasepool {
Product *product = [Product productWithItemID:@""];
// process and display the product here
}
}
}
在循环结束的时候,以及在@autoreleasepool块的尾部,所有的autoreleased对象会released。这种方法你能够控制和release所有位使用的对象和回收你的内存。
Instruments
当我讨论使用设备和模拟器测试的时候,第2章已经介绍过Instruments。在这个部分,我将简短的讨论一些更加更高级的问题,这些问题会影响到你应该选择什么样的内存管理方式。
大部分时间,你需要使用到4中主要的instruments。
Static Analyzer
Leaks Instruments
Zombie
Object allocation
Static Analyzer
static Analyzer是一个比较快速的方法检查一些微小的比较明显的内存泄露。例如,如果你alloc了一个新的对象,没有在方法内release它,如图7-10所示,Static Analyzer能够快速的发现。
Leak Instrument
Leaks Instrument更加复杂,它需要时间允许和分析,但是会给出更好的结果。在运行过程中,它能够检测到所有数据轨迹的内存泄露。
Leaks Instrument能给出内存泄露对象更多的细节信息,如图7-11.
同样能够显示泄露确切的发生在哪一行(图 7-12)。
Zombie
Zombie能够帮助你检查EXEC_BAD_ACCESS导致的应用程序崩溃的问题。这是非常有帮助的,如果你的应用老是崩溃,但是通过日志或检查代码又发现不了问题的话。
如图7-13,Zombie会显示给你一个actions的list,包括malloc,autorelease,retain,和release,当应用崩溃的时候。你使用Zombie跟踪autorelease和release方法。
Object Allocation
Object allocation是我要介绍的内存相关的最后一个工具。它显示了运行过程中,所有内存的使用情况。这个工具是非常有用的,当内存使用增长很多,你需要跟踪使用内存较多的那些代码。
图7-14显示了代码所在行,对象创建的时间,和创建对象的调用者。
Memory Waring Levels
最后我要讨论的是关于内存警告。当你的内存增长到一定点时,iOS系统会尝试告诉你,通过在view controller中调用didReceiveWarning方法。你应该在这个方法中释放一些内存。
注意:在你的应用中还有其他方法收到内存警告:applocation delegate收到内存警告,然后在其他对象中调用相应的方法,或者你的对象通过NSNotification注册了接受内存警告的通知。 |
内存警告的第1级别是最重要的:它意味着你的代码已经快速的使用了很多内存。否则,你的app将会收到第2个级别的警告,然后会崩溃。
总结
内存对你的app的性能有重要影响。如果你不恰当的使用会导致你的app崩溃。在本章,你学到了在objective-c中很多关于内存管理方面的重要概念,这能够帮助你避免内存泄露和应用程序崩溃。UIViewController的生命周期同样非常重要,因为它和内存的管理和控制有关。它同样会影响到应用的性能和体验。最后,你学到了当在处理内存时,autorelease和release的不同,以及何时应该用其中的一个替代另外一个。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。