UITableView中的ARC奇怪的释放行为

时间:2012-06-28 18:51:44

标签: objective-c ios automatic-ref-counting exc-bad-access

我最近有两次这种行为发生在我身上,我想知道问题的根本原因是什么(又如何确保这种情况永远不会发生,所以我不必浪费大量时间来修复它)。

当我在一个可以重用的tableview单元格中分配一些内容时,一旦加载另一个单元格并重新加载该表格,有时会释放该对象。

示例:

SubHolder *dataStorage;

- (void) initializeLicenseTable
    {
        LicenseCell *sampleLicense = [LicenseCell new];
        self.licenseData = [[NSMutableArray alloc] initWithObjects:sampleLicense, nil];
        nib = [UINib nibWithNibName:@"LicenseCell" bundle:nil];

    if (dataStorage == nil)
    {
        dataStorage = [SubHolder new];
        dataStorage.owner = self;
        [dataStorage addStorageLocation];
    }
} //cellForRowAtIndexPath and stuff

如果没有if语句(这会导致dataStorage变成僵尸),此代码不起作用

导致这种行为的原因是什么?看起来像测试dataStorage是否为nil只是然后分配它与修复僵尸问题的方法相反。

- 编辑 -

如果这种行为是由共享变量引起的,那么我怎样才能创建它以便每次创建这个对象的实例时它都会创建自己的数据存储对象?每个表都有自己的信息,不与其他表共享。

2 个答案:

答案 0 :(得分:2)

由于dataStorage是一个全局变量(在您的类的文件范围内可见),因此它将由您的类的所有实例共享。

现在,如果您的类的第二个实例已初始化,并且您没有检查

if (dataStorage == nil)

然后你的全局对象将被覆盖,因此在某些时候通过ARC解除分配。如果某个其他对象在某处存储了它的值,它将尝试访问旧对象并获得僵尸访问权。

编辑:

如果每个对象都需要自己的dataStorage,则只需要声明

SubHolder *dataStorage;

在您的interface声明中,或者属于:

@property (nonatomic, strong) SubHolder *dataStorage;

答案 1 :(得分:1)

看起来您只是一直在创建新的单元格,而不是重复使用它们。

您应该重复使用这样的单元格:

UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"myCell"];
if(cell == nil) 
{
    cell = [[UITableViewCell alloc] initWithStyle:aStyle reuseIdentifier:@"myCell"];
}