Jon*_*lis 2 iphone cocoa-touch objective-c ios automatic-ref-counting
我有兴趣了解如何在ARC紧密循环下最好地处理内存管理.特别是,我有一个我正在编写的应用程序,它有一个while很长时间的循环,我注意到尽管已经实现了(我相信是)ARC中的最佳实践,但堆仍然存在无限增长.
为了说明我遇到的问题,我首先设置以下测试以故意失败:
while (true) {
NSMutableArray *array = [NSMutableArray arrayWithObject:@"Foo"];
[array addObject:@"bar"]; // do something with it to prevent compiler optimisations from skipping over it entirely
}
Run Code Online (Sandbox Code Playgroud)
使用"分配"工具运行此代码和分析表明内存使用量不断增加.但是,@autoreleasepool如下所示,立即解决问题并保持内存使用的良好和低:
while (true) {
@autoreleasepool {
NSMutableArray *array = [NSMutableArray arrayWithObject:@"Foo"];
[array addObject:@"bar"];
}
}
Run Code Online (Sandbox Code Playgroud)
完善!这一切似乎都运行良好 - 它甚至可以正常工作(如预期的那样)用于使用创建的非自动释放的实例[[... alloc] init].一切正常,直到我开始涉及任何UIKit课程.
例如,让我们创建一个UIButton并看看会发生什么:
while (true) {
@autoreleasepool {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectZero;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,内存使用量无限增加 - 实际上,它似乎@autoreleasepool没有任何效果.
所以问题是为什么@autoreleasepool工作正常NSMutableArray并保持内存检查,但是当应用于UIButton堆继续增长?
最重要的是,UIKit在这样的无限循环中使用类时,如何保持堆不断扩展?这告诉我们ARC while(true)或while(keepRunningForALongTime)样式循环的最佳实践?
我对此的直觉是(而且我可能完全错了)是,它可能是关于如何while (true)使runloop保持循环,这是将UIKit实例保留在记忆中而不是释放它们......但很明显我错过了一些东西我对ARC的理解!
(并且消除了明显的原因,NSZombiedEnabled未启用.)
至于为什么UI*对象无限制地增长?内部实施细节.最有可能的是,通过阻止主运行循环有效禁用某种缓存或runloop交互.
这让我得到了真正的答案:
最重要的是,在这样的无限循环中使用UIKit类时,如何让堆不断扩展?这告诉我们在while(true)或while(keepRunningForALongTime)样式循环中ARC的最佳实践?
怎么解决? 不要在主线程上使用紧密循环,也不要阻止主运行循环.
即使您要弄清楚UI*引起的堆增长,如果您while(...)在主线程上使用循环,您的程序仍然无法工作.iOS应用程序(和Cocoa应用程序)的整个设计是主线程有一个主运行循环,主运行循环必须可以自由运行.
如果不?您的应用程序将不会响应(并最终将被系统杀死)到用户输入,并且您的绘图代码不太可能按预期工作(因为运行循环合并脏区域并根据需要与主线程一起绘制它们,oft卸载到辅助线程).
| 归档时间: |
|
| 查看次数: |
600 次 |
| 最近记录: |