对于在后台线程中调用的方法,ARC是否不再需要@autoreleasepool
?下面的代码假设导致内存泄漏,除非doStuff包含@autorelease池,但是当我运行instrument时它会显示User被分配并在runloop结束时被解除分配。
- (IBAction)buttonClicked:(id)sender {
[self performSelectorInBackground:@selector(doStuff) withObject:nil];
}
- (void)doStuff {
User *user = [[User alloc] init];
NSLog(@"%@", user);
}
答案 0 :(得分:3)
虽然在NSThread的实现中可能是对现有自动释放池的提示,但是没有这样的文档保证。相反,文档明确指出:
aSelector表示的方法必须像程序中任何其他新线程一样设置线程环境。
如果您的应用程序使用托管内存模型[MRC和ARC,而不是垃圾收集],则应在您的线程入口例程中首先创建自动释放池。
结论:虽然在某些特定情况下可能存在自动释放池,但不建议依赖此事实。它是未记录的行为,可以随操作系统的每个版本或其他情况而改变。通常应该在运输代码中避免使用它。
答案 1 :(得分:1)
我使用了以下测试应用程序:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad{
[super viewDidLoad];
[self performSelectorInBackground:@selector(doStuff) withObject:nil];
}
- (void)doStuff {
NSMutableArray *ar = [NSMutableArray array];
for (int i=0; i<1000000; i++) {
ar[i] = [NSString stringWithFormat:@"%i", i];
}
}
@end
使用分配工具对其进行分析,得到以下结果:
在调用树的第8行,使用自动释放池,虽然我没有在我的代码中设置一个。此外,后台线程分配的内存似乎已被释放
因此看起来好像后台线程安装了自动释放池。
编辑(请参阅下面的评论):
但这并不意味着没有必要为线程安装自动释放池,因为据我所知,上面显示的行为没有记录。
答案 2 :(得分:-2)
实际上,如果您没有添加autorelease
(这几乎只是在寻找麻烦),该代码应该泄漏内存(在MRC下)。但是,无论如何,我都会回答你的问题。
ARC应该不需要任何类型的内存管理(除了块和其他陷阱的 lot ,但无论如何)。但仍有自动释放的对象。 @autoreleasepool
在紧密循环等方面特别有用。仍然有游泳池消耗,您不必自己将autorelease
添加到对象。