【问题标题】:Memory leak on reloadData UICollectionViewreloadData UICollectionView 上的内存泄漏
【发布时间】:2013-10-02 06:56:44
【问题描述】:

我正在开发我的第一个 iOS 项目,应该被认为是 Objective-C 和 xcode 的初学者。

我正在构建一个应用程序,该应用程序显示数量可以从 1 到 200 项不等的项目集。我正在从 RSS 提要中检索项目并解析 XML。我已经能够毫无问题地在 UITableView 中显示项目,并且它以我想要的方式工作。

该应用程序适用于 iPhone 和 iPad(在 6.1 上测试),我的目标是在 iPad 上的 UICollectionView 和 iPhone 上的 UITableView 中显示项目。我已经能够在 collectionview 中显示项目,但是当我调用 reloadData 方法时,应用程序崩溃并出现以下错误:

“线程 1:EXC_BAD_ACCESS(代码=1,地址=0,50c1ecd9)”

在我寻找答案时,我读到打开僵尸可以帮助我找到问题,它给了我这个错误:

[CollectionCell release]:消息发送到释放实例0xc177470

# 地址类别 事件类型 RefCt 时间戳大小 责任库 责任调用者 1507 0x16941940 CollectionCell Release 1 00:21.272.192 0 UIKit-[UICollectionView reloadData] 1508 0x16941940 CollectionCell Release 0 00:21.275.833 0 基础-[NSAutoreleasePool 流失] 1509 0x16941940 CollectionCell Zombie -1 00:21.279.332 0 基础 -[NSAutoreleasePool 排水]

CollectionCell 是我的自定义 UICollectionViewCell 类。

我将提供我认为与问题根源最相关的 UITableView 和 UICollectionView 的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"NewsCell_iPhone";
UITableViewCell *cell = nil;
cell = (NewsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    NSArray *nib = nil;
    nib = [[NSBundle mainBundle] loadNibNamed:@"NewsCell_iPhone" owner:self options:nil];
    cell = [nib objectAtIndex:0];
} 

UICollectionView:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"CollectionCell";
UICollectionViewCell *cell = (CollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

if (cell == nil) {
    NSLog(@"Test");
    NSArray *nib = nil;
    nib = [[NSBundle mainBundle] loadNibNamed:@"CollectionCell_iPad" owner:self options:nil];
    cell = [nib objectAtIndex:0];
}

NewsCell (UITableViewCell)

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
    // Initialization code
}
return self;
}

CollectionCell (UICollectionViewCell)

- (id)initWithFrame:(CGRect)frame {

self = [super initWithFrame:frame];

if (self) {
    // Initialization code
    NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"CollectionCell" owner:self options:nil];

    if ([arrayOfViews count] < 1) {
        return nil;
    }

    if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
        return nil;
    }

    self = [arrayOfViews objectAtIndex:0];
}
return self;
}

我希望我已经包含了解决此问题所需的内容,我愿意接受任何改进我的代码的建议。

【问题讨论】:

  • 我认为您没有包含所有内容。查看错误,它显示 [CollectionCell release]
  • 我不会在代码中的任何地方发布 CollectionCell,至少不是手动发布,因为我找不到发布调用。我猜它与 initWithFrame 方法有关,我是从教程中获取的。
  • 它关闭了,认为默认情况下是这样的,我不确定启用它的优点/缺点是什么。
  • 我相信您在 CollectionCell 的 initWithFrame 方法上缺少保留:self = [[arrayOfViews objectAtIndex:0] retain]; 另一方面,如果您对它相当陌生,并且没有最新的内存管理层,您可能确实想打开 ARC,就像 Zsolt 勋爵所说的那样。

标签: ios objective-c xcode memory-leaks


【解决方案1】:

看到您的代码以及您对 ARC 已关闭的评论,很可能发生内存泄漏,因为您正在为对象分配空间,但从未释放它。

如果您不熟悉编程,特别是动态内存管理,我建议您打开 ARC,这样您就不必担心释放对象。

另外,请按照您的教程进行操作,如果 ARC 已打开,请将其打开,如果已关闭,请将其关闭。这是因为如果它在教程中打开,它不会实现 dealloc 方法,该方法服务于释放内存的目的。

【讨论】:

  • 感谢您和 Nerkatel 的建议。自从我一直(自动)发布以来,打开 ARC 会导致大量错误,因为它包含在我遵循的其他教程中。我将在下一个项目中打开 ARC。 Nerkatel 的回答暂时解决了这个问题,我将阅读更多关于内存管理的内容,以防止我犯同样的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
  • 2017-02-28
相关资源
最近更新 更多