在ARC中,viewDidLoad过早地解除了分配?

时间:2015-05-20 01:05:32

标签: objective-c macos automatic-ref-counting

我正在编写一个具有<!DOCTYPE html> <html> <head> <style> html { height:100%; width:100%; background-image:url("file://C:\Users\Public\Pictures\Sample Pictures\florida-orlando-resort.jpg"); } </style> </head> <body> 123...<img src="C:\Users\Public\Pictures\Sample Pictures\florida-orlando-resort.jpg" style="width:100px; height:100px; display:cover;">...456 </body> </html> 的应用程序,以及一个实现NSOutlineView的界面。但是,在运行时,应用程序崩溃时出现错误消息已发送到解除分配的实例。我做了一些关于僵尸和仪器的调试,我找到了解除分配的地址。

Instruments

我无法弄清楚这里发生了什么。我已经确定如果我为ViewController.m禁用ARC,它就不会发生段错误。这是相关的代码。

NSOutlineViewDataSource

这是ArrayOutlineDataSource,它实现了NSOutlineViewDataSource。

-(void)viewDidLoad {
    [super viewDidLoad];
    NSArray * array = [[NSArray alloc]initWithObjects:@"chrisdotcode",@"Mop",@"ollien", nil];
    [self.namesList setDataSource:[[ArrayOutlineDataSource alloc] init:array]];
}

1 个答案:

答案 0 :(得分:1)

documentation说:

  

大纲视图不拥有其数据源。同样,它不拥有从数据源获取的对象 - 如果它们被释放,您的应用程序可能会崩溃,除非您告诉大纲视图重新加载其数据。

     

数据源是一个控制器对象,您负责确保在大纲视图完成之前不会释放它(通常数据源是一个对象,例如基于文档的应用程序中的文档对象,所以没有额外的工作要做)。数据源又负责保留它为大纲视图提供的所有对象,并在模型发生更改时更新大纲视图。因此,释放根项目或任何子项目是不安全的,直到您不再在大纲视图中显示它。

底线,大纲视图不保持对其数据源的强引用。 (这很常见:通常数据源和委托是弱引用。)问题中的代码示例不保留ArrayOutlineDataSource

创建自己的属性以维护对此ArrayOutlineDataSource的强引用:

@property (nonatomic, strong) ArrayOutlineDataSource *dataSource;

然后:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray * array = [[NSArray alloc]initWithObjects:@"chrisdotcode",@"Mop",@"ollien", nil];
    self.dataSource = [[ArrayOutlineDataSource alloc] init:array];
    [self.namesList setDataSource:self.dataSource];
}