cellForRowAtIndexPath内存管理

Rob*_*Rob 2 iphone memory-management uitableview uikit ios

所以,这是我的cellForRowAtIndexPath的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"identifier"];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"identifier"]autorelease];
    }

    NSInteger artistIndex = 1; // 1
    NSInteger albumIndex = 3;  // 3
    NSInteger dateIndex = 6;   // 6
    NSInteger imageIndex = 8;  // 5

    // ARTIST
    CGRect frame = CGRectMake(59, 11, 244, 13);
    UILabel *label = [[UILabel alloc]initWithFrame:frame];
    label.font = [UIFont boldSystemFontOfSize:13];
    label.textColor = [UIColor blackColor];
    label.text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:artistIndex];
    [cell addSubview:label];

    // ALBUM (more like description...
    frame = CGRectMake(60, 30, 244, 11);
    label = [[UILabel alloc]initWithFrame:frame];
    label.font = [UIFont boldSystemFontOfSize:11];
    label.textColor = [UIColor darkGrayColor];
    label.text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:albumIndex];
    [cell addSubview:label];

    // DATE
    frame = CGRectMake(59, 49, 244, 10);
    label = [[UILabel alloc]initWithFrame:frame];
    label.font = [UIFont fontWithName:@"Helvetica" size:10.0];
    label.textColor = [UIColor darkGrayColor];
    label.textAlignment = UITextAlignmentRight;
    label.text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:dateIndex];
    [cell addSubview:label];

    // IMAGE
    UIImageView *imageView = [[UIImageView alloc]init];
    imageView.image = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:imageIndex];
    imageView.frame = CGRectMake(8,9,44,44);
    [imageView.layer setMasksToBounds:YES];
    [imageView.layer setCornerRadius:3.0];
    [[cell contentView] addSubview:imageView];

    [imageView release];
    [label release]; 

    return cell;
}
Run Code Online (Sandbox Code Playgroud)

为了解释发生了什么,基本上它只是点击一个数组,存储除索引8(存储UIImage)之外的所有内容的字符串.

我没有设置自动释放的变量(主要是因为我真的不明白autorelease只是lol)

无论如何,当滚动应用程序时,它将逐渐减慢(主要是因为UIImage,但也部分是因为标签和框架).

无论如何更好地管理我的记忆?还有,有更好的编码方式吗?我正在考虑制作一个UITableViewCells数组,并通过cellForRowAtIndexPath访问它们.

所以我很想得到一些建议,谢谢你们.

Nic*_*ood 12

你在那里泄漏了很多标签.每次分配/初始化新标签时都需要释放它.目前,您通过为其分配新标签对象而不释放旧标签对象,多次重复使用相同的标签变量.

而不是将[标签发布]放在最后,在每个[cell addSubview:label]之后放置[label release];

您的下一个问题是您误解了表格单元回收的工作原理.UITableCell对象在表中反复使用,这就是为什么你这样做的原因:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"identifier"];

if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"identifier"]autorelease];
}
Run Code Online (Sandbox Code Playgroud)

这基本上是说"检查是否有可用的单元格,如果没有可用的单元格".重新使用一个单元格时,它会保留您添加到其中的所有旧内容.因此,当您将这些标签和图像视图添加到单元格时,它们将在下次使用时保留在该单元格中,并在下次使用时保留在该单元格中.

但是因为每次重复使用单元格时都会再次添加标签,所以它会构建标签的多个副本,因此第二次显示单元格时标签的数量是标签的两倍,下一次是标签的3倍,等等.您无法看到重复项,因为它们位于完全相同的位置,但它们会占用内存并减慢您的桌面速度.

您需要将代码添加到"if(cell == nil){...}"语句中的单元格中,因此标签仅在创建单元格时添加一次.

当然,这意味着每个单元格都具有相同的文本和图像,这是您不需要的,因此您需要拆分设置文本和图像的逻辑,并将其放在if语句之后.这样您只需创建一次标签,但每次在不同的表格行中显示时都会设置文本.这有点棘手,因为你没有对标签的引用,但你可以通过在标签上设置唯一标签来做到这一点,这样你就可以再次找到它们.

这是一个清理过的版本,删除了所有泄漏:

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"identifier"];

    NSInteger artistTag = 1;
    NSInteger albumTag = 2;
    NSInteger dateTag = 3;
    NSInteger imageTag = 4;

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"identifier"]autorelease];

        // ARTIST
        CGRect frame = CGRectMake(59, 11, 244, 13);
        UILabel *label = [[UILabel alloc]initWithFrame:frame];
        label.font = [UIFont boldSystemFontOfSize:13];
        label.textColor = [UIColor blackColor];
        label.tag = artistTag;
        [cell addSubview:label];
        [label release];

        // ALBUM (more like description...
        frame = CGRectMake(60, 30, 244, 11);
        label = [[UILabel alloc]initWithFrame:frame];
        label.font = [UIFont boldSystemFontOfSize:11];
        label.textColor = [UIColor darkGrayColor];
        label.tag = albumTag;
        [cell addSubview:label];
        [label release];

        // DATE
        frame = CGRectMake(59, 49, 244, 10);
        label = [[UILabel alloc]initWithFrame:frame];
        label.font = [UIFont fontWithName:@"Helvetica" size:10.0];
        label.textColor = [UIColor darkGrayColor];
        label.textAlignment = UITextAlignmentRight;
        label.tag = dateTag;
        [cell addSubview:label];
        [label release];

        // IMAGE
        UIImageView *imageView = [[UIImageView alloc]init];
        imageView.frame = CGRectMake(8,9,44,44);
        imageView.tag = imageTag;
        [imageView.layer setMasksToBounds:YES];
        [imageView.layer setCornerRadius:3.0];
        [[cell contentView] addSubview:imageView];
        [imageView release];
    }

    NSInteger artistIndex = 1; // 1
    NSInteger albumIndex = 3;  // 3
    NSInteger dateIndex = 6;   // 6
    NSInteger imageIndex = 8;  // 5

    ((UILabel *)[cell viewWithTag:artistTag]).text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:artistIndex];

    ((UILabel *)[cell viewWithTag:albumTag]).text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:albumIndex];

    ((UILabel *)[cell viewWithTag:dateTag]).text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:dateIndex];

    ((UIImageView *)[cell viewWithTag:imageTag]).image = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:imageIndex];


    return cell;
} 
Run Code Online (Sandbox Code Playgroud)

  • 对于"为什么我的桌子看不起作用?"的规范回答,这是一个很好的答案和强有力的候选人.在这里经常弹出的问题. (2认同)

Wol*_*urs 5

为了提高内存使用效率并获得更流畅的滚动性能,您应该创建一个自定义UITableViewCell子类,其中包含一个自定义UIView作为UITableViewCell的contentView的子视图.您应该使用-drawRect:绘制此自定义视图.具有大视图层次结构是非常占用内存的,而不是只有一个视图,所有内容都直接在其上绘制.

Apple的TableViewSuite示例实际上包含了这种直接绘图方法的示例.在这里下载项目:

http://developer.apple.com/library/ios/#samplecode/TableViewSuite/Introduction/Intro.html

查看第五个示例,了解如何在您自己的项目中实现高性能,低内存自定义tableview单元格绘制.