记忆管理问题

时间:2011-04-01 22:35:00

标签: iphone objective-c memory-management

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *TelephoneCellId = @"TelephoneCellId";

    UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:TelephoneCellId];

    UIImageView *imgView;
    UILabel *lblName;
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TelephoneCellId] autorelease];

        UIView *uiview = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 90.0)];

        imgView = [[[UIImageView alloc] initWithFrame:CGRectMake(10.0, 10.0, 60.0, 60.0)] autorelease];
        imgView.tag = IMAGE_TAG;
        [uiview addSubview:imgView];

        lblName = [[[UILabel alloc] initWithFrame:CGRectMake(80.0, 10.0, 200.0, 20.0)] autorelease];
        lblName.tag = NAME_TAG;
        [uiview addSubview:lblName];

        [cell.contentView addSubview:uiview];
        [uiview release];
    } else {
        imgView = (UIImageView *)[cell.contentView viewWithTag:IMAGE_TAG];
        lblName = (UILabel *)[cell.contentView viewWithTag:NAME_TAG];
    }

    NSDictionary *dict = [[[self.telephoneList objectForKey:[self.keys objectAtIndex:[indexPath section]]] objectAtIndex:[indexPath row]] retain];
    imgView.image = [UIImage imageNamed:[dict objectForKey:@"image"]];

    lblName.text = [dict objectForKey:@"name"];

    [dict release];
    return cell;
}

在上面的代码中,我得到了一个关于保留和自动释放的问题。如果从que返回的UITableViewCell是nil,那么我必须创建一个新的。当我这样做时,我自动发布标签和图像。然后我设置文本/图像。如果UITableViewCell不是nil,那么我会通过标签找到视图,但是这将返回一个自动释放的对象。我应该保留吗?然后在我完成设置值后释放?或者是这个okey因为视图保留它所以它至少是1因此不释放是安全的吗?

非常感谢有关此类场景的帮助,总而言之,何时可以在自动释放的对象上继续设置/获取值?

感谢您的时间:)

3 个答案:

答案 0 :(得分:2)

你已经在想这个了。

您是否希望此功能获取对象的所有权(因此,对此负责)?不,当然不。因此,不要为了这个功能而保留。

您是否希望此代码所在的视图控制器对某个对象负责?不:你想把它放在UIKit的手里。因此,不要为视图控制器保留。

结论:如果您不想取得所有权,则不予保留。

另外,不要费心保留(以及稍后发布)字典。即使它已被自动释放到它很快就会消失的程度,但这个功能正在运行时“很快”将不会出现。

答案 1 :(得分:2)

如果你有一个 auto 发布的对象,你可以操纵它的属性,将一个参数传递给其他方法,甚至将它作为方法的返回值返回。但是你不能将它存储在ivar,全局变量或静态变量中而不保留它。

但是,您通过标签找到的标签实际上并未实际自动释放。它只是一个你不拥有的对象。您可以保留然后释放它,但这不是必需的。

需要注意的主要情况是:

  • 从集合中获取对象然后从集合中删除该对象时,该集合将释放该对象。因此,如果你想保留它,你将不得不保留它。
  • 当你编写一个setter方法时,你必须小心处理有人有效[object setFoo:object.foo]的情况。如果您在保留新值之前释放旧值,那么最终可能会将retain发送到已解除分配的对象。

答案 2 :(得分:0)

是的,没有必要保留它。您也不需要保留和发布字典。