loadNibNamed topLevelObjects的泄漏

时间:2013-04-19 14:02:44

标签: ios objective-c uitableview automatic-ref-counting loadnibnamed

我正在使用自定义单元格,我拨打loadNibNamed:。这似乎导致内存泄漏,我不知道如何解决它。如果我之后将顶级对象设置为nil,我仍然会得到泄漏。

topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];

然后我这样做

for (id currentObject in topLevelObjects){
        if ([currentObject isKindOfClass:[UITableViewCell class]]){
            cell =  (CustomCell *) currentObject;
            break;
        }
    }

然后改变单元格上的属性。

自定义单元格具有对属性的强引用,它不是循环引用,因此我不确定这是否是问题。使用ARC时,停止这种废弃内存的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

我怀疑你的泄漏可能来自笔尖的出口。请注意loadNibNamed:上的docs中的这句话:

  

要建立插座连接,此方法使用setValue:forKey:方法,这可能会导致插座中的对象自动保留。

换句话说,loadNibNamed有时会因为键值编码的奇怪方式而产生额外的保留。

然而,这是猜测,并且没有必要,因为您无需首先致电loadNibNamed:

你正在使用一个自定义的UITableViewCell子类,用nib设计?那么为什么不以正常的方式做到这一点?创建一个包含一个顶级对象的nib:该单元格。在nib中设计单元格,设置其类,连接其出口等。在代码中,在表视图上调用registerNib:forCellReuseIdentifier:,以告诉表视图有关您的笔尖。当您稍后调用dequeueReusableCellWithIdentifier:时,如果重用堆中没有空闲单元格,则表视图将加载您的笔尖并将您的单元格移交给您。没有麻烦,没有大惊小怪。

答案 1 :(得分:1)

马特的回答很明显。这是代码的样子。修正了我的记忆问题,因为现在单元格已加载并且应该出列。

首先,注册笔尖

[self.tableView registerNib:[UINib nibWithNibName:@"customCell"
                                           bundle:nil] 
                           forCellReuseIdentifier:@"customCellID"];

...其次

CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"customCellID"];

笔尖只需要一个tableviewcell,你就可以了!

答案 2 :(得分:0)

请考虑使用UINib。 UINib将nib文件的内容缓存在内存中,从而节省了到文件系统的行程。例如,您可以在属性中创建nib和reference的实例:

self.cellNib = [UINib nibWithNibName:@"customCell" bundle:nil];

在nib文件中,将单元格绑定到表视图控制器的属性。然后,只要您需要单元格的实例,请求UINib实例为您实例化,并且对新单元格的引用将自动存储在属性中。

[self.cellNib instantiateWithOwner:self options:nil];
cell = self.customCell;
self.customCell = nil;

此方法应有助于避免使用顶级对象数组时遇到的内存管理问题,并显着提高性能。