我理解自动引用计数的工作原理:
在编译时,确定对象之间可能的关系类型,从而确定可能发生的版本,然后在运行时,跟踪每个对象的强指针引用数,并在该数字达到0时释放。至少在处理主线程时,我还没有在概念或实践中遇到过这方面的问题。
我注意到当我开始一个新的后台线程时,它不会释放任何生成的对象,直到线程结束。我举了一个例子:
本质上,在线程调用周围放置了一个自动的“@autoreleasepool”,因此显而易见的是,放置我自己的不会解决这个问题。事实上,我已经测试了相同的结果。如果我是正确的,那么强制池的存在正是导致我的问题,但我认为这是ARC可以在多线程应用程序上执行的最佳。内存使用缓慢而持续地倾斜。如果我将此线程留得太久,应用程序最终会耗尽内存。这是一个问题,因为线程需要能够在最坏的情况下无限期地运行。
我已经删除了线程中的一些主要分配。我相信我已经确定剩下的一些内存分配是从NSMutableArray释放的NSNumbers,因为我覆盖了它。
所以我想我必须做以下其中一项:
这些看起来都不是解决我问题的方法,虽然我可以尝试1或6.有没有人有建议?
更新:
我运行了相同的算法但是在代码中添加了以下自动释放块,起初我认为我会反驳rmaddy和Aaron Brager的回应。
-(void)setInt: (int)value For: (NSString *)variableName {
@autoreleasepool {
[self.intDictionary setValue:@(value) forKey:variableName];
}
}
-(void)setBool: (bool)value For: (NSString *)variableName {
@autoreleasepool {
[self.boolDictionary setValue:@(value) forKey:variableName];
}
}
以下是生成的内存分配图:
他们是对的。我很高兴在这种情况下我错了。这意味着我的编码将比我开始想象的容易得多。
答案 0 :(得分:5)
自动释放的对象在其自动释放池耗尽时被释放。这通常发生在线程运行循环的末尾。
无论您是在谈论主线程还是后台线程,这种行为都是一样的。当然,它仅适用于不再具有强引用的对象。
对你的分析并不完全正确:
基本上,在线程调用周围放置了一个自动的“@autoreleasepool”,因此显而易见的是,放置我自己的不会解决这个问题。
考虑以下代码:
@autoreleasepool {
for (int i = 0; i < 100000; i++) {
// create an expensive autoreleased object
// do something with it
}
}
在这种情况下,当自动释放池耗尽时,直到运行循环结束时才会解除分配自动释放的对象。
但是,如果您添加自己的自动释放池:
@autoreleasepool {
for (int i = 0; i < 100000; i++) {
@autoreleasepool {
// create an expensive autoreleased object
// do something with it
}
}
}
对于for
循环的每次迭代,当内池耗尽时,对象将被释放。
如果如上所示添加您自己的自动释放池无法解决您的问题,那么剩下的可能性是:
CGImageRef
而从未调用CGImageRelease
)release
)您提出的六个解决方案也可以解决问题,但修复起来可能更容易。