【问题标题】:UITableViewCell Identifier without ARC floods memory没有 ARC 的 UITableViewCell 标识符会淹没内存
【发布时间】:2014-03-06 13:56:35
【问题描述】:

我正在处理一个没有 ARC 的旧项目。它有很多错误,代码看起来很丑,我正在重写它。

快速查看我的代码

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [self.table dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    cell = [self createCellWithInfo:[self.search objectAtIndex:indexPath.row]];
    return cell;
}

-(UITableViewCell *)createCellWithInfo:(NSDictionary *)info{

    UITableViewCell * cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@“Cell”] autorelease];
    //set image for cell
    //set text for cell.textlabel
    //set text for cell.detailTextLabel
    //create an UIButton and add to cell.content view
    return cell;
}

重点在这行代码 [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@“Cell”] autorelease]

如果我在这里使用@"Cell",那么当我在桌子上连续上下滚动时,内存会上升。 滚动大约 15 秒后,我的 iphone 5c 变得滞后。

如果我将它设置为nil,一切都很好。

有人可以解释一下吗?我不熟悉非ARC。

谢谢。

【问题讨论】:

  • 在 Objective C 中评估的一个好习惯是:if (!cell) 而不是 if (cell == nil)
  • 除非有充分的理由不点击“编辑 -> 转换为 Obj-C ARC”?
  • 我同意@MikePollard,我敢打赌这个应用比爱德华·斯诺登泄漏更多。
  • 大声笑,这是一个非常生动的比较。回到主题,如果我可以将其转换为 ARC,我会这样做,但它包含一些不支持 ARC 的旧添加类,例如 ASIHTTPRequest。我添加了-fnc -objc -arc,但出现了一些其他错误,我正在处理它。同时,这个项目还要继续推进,你知道的......

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


【解决方案1】:

if 块中,您在没有调用自动释放的情况下创建单元格,这会在没有 ARC 的情况下泄漏内存。

if 块之后,无论如何您都在重新创建它(无论它是否被回收),这次使用自动释放,您真正应该做的就是重置其相关​​属性,以便您可以成功重用回收的单元格(或配置新单元格)。

尝试如下替换您的代码:

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

    [self updateCell:cell withInfo:[self.search objectAtIndex:indexPath.row]];
    return cell;
}

-(void)updateCell:(UITableViewCell *)cell withInfo:(NSDictionary *)info{
    //set image for cell
    //set text for cell.textlabel
    //set text for cell.detailTextLabel
    //create an UIButton and add to cell.content view
}

【讨论】:

  • 顺便说一句,你需要autorelease的原因是因为每个init*都必须与一个release配对,但是由于你返回后不能释放cell,所以你推迟释放致电autorelease
【解决方案2】:
UITableViewCell *cell = [self.table dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}

单独负责单元初始化,您不需要另一行。

【讨论】:

  • .. 但它可能应该有一个自动释放。
  • @JamesWebster 是的。自从我非ARC'd以来已经有很长时间了! :)
猜你喜欢
  • 2012-03-12
  • 2012-02-25
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-07
相关资源
最近更新 更多