内存泄漏UITableView

时间:2013-12-07 11:17:12

标签: ios objective-c uitableview memory-leaks

请阅读@Kjuly

的答案

非常感谢

问题

我将tableView与section一起使用,每个部分有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];



        }

    }

3 个答案:

答案 0 :(得分:1)

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

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

更新问题的编辑:

你需要知道“细胞重用”是如何工作的。至于你的更新代码,它说只有第1行需要像图像这样的子视图,对吧?因此,您需要将其添加到if (cell == nil){}代码段之外,如下面的代码所示:

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行一样创建一个新的单元格实例,因为它只需要创建一次。

答案 1 :(得分:0)

试试这个......

男人你在这里犯了两个错误

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

  2. 分配单元格后
  3. ,你没有释放它的内存。

  4. 我建议您使用此代码。

    - (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];
           }
    }
    

    不要忘记自动释放细胞。

答案 2 :(得分:0)

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

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