【问题标题】:Retain count issue in iPhone SDKiPhone SDK 中的保留计数问题
【发布时间】:2011-11-01 09:48:39
【问题描述】:

我对检查对象的保留计数有一点疑问:

请看下面的代码,释放对象内存后显示retainCount为1。

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        CGRect contentRect = [cell.contentView bounds];     
        UIImageView *thumbView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:IMAGE_CELL_BACKGROUND]];
        thumbView.frame = contentRect;      
        cell.backgroundView=thumbView;
        [thumbView release];
    }
    UIImageView *image=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"left_arrow.png"]];
    **NSLog(@"Image retain count %d",[image retainCount]);**
    image.frame=CGRectMake(290, 12.5, [UIImage imageNamed:@"left_arrow.png"].size.width,  [UIImage imageNamed:@"left_arrow.png"].size.height);
    image.backgroundColor=[UIColor clearColor];
    [cell.contentView addSubview:image];
    [image release];
    **NSLog(@"Image retain count-- after %d",[image retainCount]);**


        // Configure the cell...

    return cell;
}

【问题讨论】:

  • 您真的不应该依赖retainCount 值。更多解释见this question
  • 我会更强烈地说:retainCount 比没用更糟糕。你不能相信它可以帮助你,因为它很可能带你走错路和/或迷惑你。根据内存管理编程指南的规定考虑所有权,如果您必须查看保留和释放(仅用于调试目的!),请改用 Instruments 的 Leaks 模板。

标签: iphone cocoa memory-management


【解决方案1】:

这是完全正常的。 cell.contentView 仍然保留对图像的引用。当您调用[cell.contenetView addSubview:image] 时,cell.contentView 将图像引用存储在某处(可能在数组或类似的东西中),并将引用计数器增加 1 以确保在 cell.contentView 仍在使用时不会释放 image它。每当cell.contentView因任何原因被释放时,它都会确保图像的保留计数减少1。

【讨论】:

  • 嗨,Tamas,你能帮我在这种情况下如何管理内存。
  • 如果我说 image=nil 而不是 [image release],这是一种很好的做法,对不起我的问题。我必须学习内存管理。
  • 不,因为这样做会泄露参考。 (您拥有对 image 的引用,因为您使用 init... 方法对其进行了初始化,因此您必须在不再需要 image 的地方释放该引用)。
  • @VsN: 更具体地说,为image 变量分配一个新值与向image 对象发送release 消息不同(更准确地说,指针为在image 变量中)。只有发送release 消息才能释放对象。发送autorelease 消息会导致池稍后向对象发送release 消息。分配给变量会导致release 消息根本不存在。
【解决方案2】:

addSubview:[image release] 之前的行中调用会导致单元格的contentView 保留图像视图,因此完全可以预期保留计数在此之后为 1 - 如果它为零则非常糟糕,因为你(或者更确切地说是单元格的contentView)仍然需要图像视图在内存中。

通过释放它,您基本上赋予了contentView 释放图像视图的唯一责任,当它自己释放或不再需要它时(例如,如果removeFromSuperview 被调用)。

【讨论】:

    猜你喜欢
    • 2023-03-15
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 2011-07-04
    • 1970-01-01
    相关资源
    最近更新 更多