可以通过发送一个-release
或-autorelease
消息来释放一个对象。
随着-release
引用计数立即递减,这可能导致释放。
随着-autorelease
递减的延迟,以使对象在其创建范围之外保持活动状态。例如,辅助方法-createFoo
可以返回一个自动释放的对象,以便调用者可以使用返回的对象,而无需在从方法返回时立即释放它,也不必担心谁负责释放它。
使用 ARC,编译器会为您处理所有这些细节。您需要知道的是,有时使用autorelease
.
这种“保持活动”行为对以下循环有影响:
- (void)foobar
{
for (/* a long time */) {
NSMutableString *s = [NSMutableString string];
// ...
}
}
+string
on 方法将NSMutableString
返回一个自动释放的对象。这不会在循环迭代或方法结束时自动释放(嗯,ARC 可以通过查看调用堆栈进行一些巧妙的优化,但我们将忽略这一点)。这意味着当您在循环体内时,您将获得无限的内存增长。
请注意,如果我们使用了以下内容:
NSMutableString *s = [[NSMutableString alloc] init];
然后 ARC 将release
在循环体的末尾插入一个调用,并且该字符串将立即被释放。
为了解决第一个示例的无限内存增长,您定义了一个显式自动释放池:
- (void)foobar
{
for (/* a long time */) {
@autoreleasepool {
NSMutableString *s = [NSMutableString string];
// ...
}
}
}
现在,在循环的每次迭代之后,自动释放池都会被销毁,并且在池中自动释放的任何对象(包括我们的字符串)都将立即释放。
所以这一切都取决于您调用的方法类型以及它们是否返回自动释放的对象。