【问题标题】:Memory Leak UITableView内存泄漏 UITableView
【发布时间】:2013-12-24 19:04:41
【问题描述】:

解决方案

@Kjuly的回答就行了

非常感谢

问题

我使用带部分的 tableView,每个部分有 4 行,第一行必须显示来自网站的图像,我使用 HJCache 类缓存图像并避免泄漏/内存问题。

现在,这段代码运行良好,当我快速滚动时它不会泄漏或造成内存问题

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //UITableViewCell *cell=nil;

    if (indexPath.row == 0) {
    static NSString *CellIdentifier = @"Cell";
    HJManagedImageV* mi;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];


        mi = [[HJManagedImageV alloc] initWithFrame:CGRectMake(0,0,cell.frame.size.width, 310)];
        mi.tag = 999;

        [cell addSubview:mi];

    } else {
        mi = (HJManagedImageV*)[cell viewWithTag:999];
        [mi clear];

    }



    if (indexPath.row == 0) {

        mi.image = [UIImage imageNamed:@"placeholder"];

    mi.url = [NSURL URLWithString:[pictures objectAtIndex:indexPath.section]];

    [objMan manage:mi];
        UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(likeTappedDouble:)];
        tapped.numberOfTapsRequired = 2;

        [mi setUserInteractionEnabled:YES];
        [mi addGestureRecognizer:tapped];



    }

        return cell;

    }
}

但是当我尝试配置其他行时,它会泄漏,并且在滚动应用程序时会出现内存问题并且速度非常慢。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //UITableViewCell *cell=nil;

    if (indexPath.row == 0) {
    static NSString *CellIdentifier = @"Cell";
    HJManagedImageV* mi;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];


        mi = [[HJManagedImageV alloc] initWithFrame:CGRectMake(0,0,cell.frame.size.width, 310)];
        mi.tag = 999;

        [cell addSubview:mi];

    } else {
        mi = (HJManagedImageV*)[cell viewWithTag:999];
        [mi clear];

    }



    if (indexPath.row == 0) {

        mi.image = [UIImage imageNamed:@"placeholder"];

    mi.url = [NSURL URLWithString:[pictures objectAtIndex:indexPath.section]];

    [objMan manage:mi];


        UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(likeTappedDouble:)];
        tapped.numberOfTapsRequired = 2;

        [mi setUserInteractionEnabled:YES];
        [mi addGestureRecognizer:tapped];



    }

        return cell;

    }



    static NSString *CellIdentifier = @"CellS";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];



    if (indexPath.row == 1) {
        // configure row 1
    }
        if (indexPath.row == 2) {
            // configure row 2
        }

    // etc for the others ..

    return cell;
}

问题出在哪里,谢谢..

更新

这段代码不好用,它在滚动时将子视图添加到另一行

 static NSString *CellIdentifier = @"CellS";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

        if (indexPath.row == 1) {
            UIImage* likesimage = [UIImage imageNamed:@"likespic"];
            CGRect frameimg = CGRectMake(7, 5, likesimage.size.width, likesimage.size.height);
            likesbutton = [[UIButton alloc] initWithFrame:frameimg];
            [likesbutton setBackgroundImage:likesimage forState:UIControlStateNormal];
            likesbutton.backgroundColor = [UIColor clearColor];
            [cell addSubview:likesbutton];

            label3 = [[UILabel alloc] initWithFrame:CGRectMake(20, 2, 100, 20)];
            label3.textColor = [UIColor colorWithRed:61.0/255.0 green:113.0/255.0 blue:154.0/255.0 alpha:1.0];
            label3.backgroundColor = [UIColor clearColor];
            label3.font = [UIFont fontWithName:@"Helvetica-Bold" size:12];
            label3.adjustsFontSizeToFitWidth = YES;

            [cell addSubview:label3];



        }

    }

【问题讨论】:

    标签: ios objective-c uitableview memory-leaks


    【解决方案1】:

    对于您的其他单元格,您需要重复使用该单元格:

    static NSString *CellIdentifier = @"CellS";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    

    编辑更新问题:

    您需要了解“单元重用”的工作原理。至于您更新的代码,它说只有第 1 行需要像图像这样的子视图,对吗?所以你需要将它添加到if (cell == nil){} sn-p 之外,如下面的代码:

    static NSString *CellIdentifier = @"CellS";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
      cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    
    if (indexPath.row == 1) {
      UIImage* likesimage = [UIImage imageNamed:@"likespic"];
      CGRect frameimg = CGRectMake(7, 5, likesimage.size.width, likesimage.size.height);
      likesbutton = [[UIButton alloc] initWithFrame:frameimg];
      [likesbutton setBackgroundImage:likesimage forState:UIControlStateNormal];
      likesbutton.backgroundColor = [UIColor clearColor];
      [cell addSubview:likesbutton];
    
      label3 = [[UILabel alloc] initWithFrame:CGRectMake(20, 2, 100, 20)];
      label3.textColor = [UIColor colorWithRed:61.0/255.0 green:113.0/255.0 blue:154.0/255.0 alpha:1.0];
      label3.backgroundColor = [UIColor clearColor];
      label3.font = [UIFont fontWithName:@"Helvetica-Bold" size:12];
      label3.adjustsFontSizeToFitWidth = YES;
    
      [cell addSubview:label3];
    }
    

    注意:最好像第 0 行那样创建一个新的单元格实例,因为它只需要创建一次。

    【讨论】:

    • 问题是当我做 cell == nil 时,子视图在每个单元格中重复,有些超过了一些
    • 它有这样的问题 *** 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'-[TimeLineViewController setTableViewStyle:]: unrecognized selector sent to instance 0x16e72800' *** First throw call stack :
    • 添加了返回单元格; ..这就是我正在寻找的非常感谢
    • @hazazezan 是的,只是一个示例代码 sn-p 向您展示正确的方法。 :)
    【解决方案2】:

    试试这个……

    你在这里犯了两个错误

    1. 不检查出队的单元格。

    2. 分配单元后,您并没有释放它的内存。

    我为你推荐这个代码。

    - (UITableViewCell *)tableView:(UITableView *)tableView 
                                 cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
           static NSString *CellIdentifier = @"cellID";
           UITableViewCell *cell = [tableView    
                                  dequeueReusableCellWithIdentifier:CellIdentifier];
           if (cell == nil)
           {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                              reuseIdentifier:CellIdentifier] autorelease];
           }
    }
    

    别忘了自动释放单元格。

    【讨论】:

      【解决方案3】:

      删除所有添加的子视图,然后添加新的子视图

      NSArray *subviews = [[NSArray alloc] initWithArray:cell.contentView.subviews];
      for (UIView *subview in subviews) {
          [subview removeFromSuperview];
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-09
        • 2011-10-23
        • 2013-11-06
        • 2011-06-03
        • 2012-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多