目标C - ARC,内存管理和performSelectorInBackground?

时间:2014-08-12 04:38:46

标签: objective-c memory-management

对于在后台线程中调用的方法,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);
}

3 个答案:

答案 0 :(得分:3)

虽然在NSThread的实现中可能是对现有自动释放池的提示,但是没有这样的文档保证。相反,文档明确指出:

performSelectorInBackground:withObject:

  

aSelector表示的方法必须像程序中任何其他新线程一样设置线程环境。

Threading Programming Guide

  

如果您的应用程序使用托管内存模型[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

使用分配工具对其进行分析,得到以下结果:
enter image description here
在调用树的第8行,使用自动释放池,虽然我没有在我的代码中设置一个。此外,后台线程分配的内存似乎已被释放 因此看起来好像后台线程安装了自动释放池。

编辑(请参阅下面的评论):

但这并不意味着没有必要为线程安装自动释放池,因为据我所知,上面显示的行为没有记录。

答案 2 :(得分:-2)

实际上,如果您没有添加autorelease(这几乎只是在寻找麻烦),该代码应该泄漏内存(在MRC下)。但是,无论如何,我都会回答你的问题。

ARC应该不需要任何类型的内存管理(除了块和其他陷阱的 lot ,但无论如何)。但仍有自动释放的对象。 @autoreleasepool在紧密循环等方面特别有用。仍然有游泳池消耗,您不必自己将autorelease添加到对象。