何时何地不向对象分配内存

时间:2012-03-23 05:50:47

标签: objective-c memory-management ownership

NSArray *array = [dictionary objectForKey:@"field"];

NSArray *array = [[NSArray alloc] initWithArray:[dictionary objectForKey:@"field"]];

我在目标C代码中经常看到这两种方法。 当试图理解时,我发现它们也在类似的情况下使用,这就产生了矛盾。我不知道何时应该使用第一种方法和第二种方法? 有什么想法吗?

欢迎妈妈们提供详细的解释和有用的参考资料。

2 个答案:

答案 0 :(得分:1)

首先,这两个例子的做法略有不同。一种是从现有字典中检索某些内容,一种是通过从现有字典中检索某些内容来创建一个新数组(该键的值是一个数组)。

但是,如果你问的是通过alloc和方便方法获取对象之间的区别。 ([NSString alloc] init vs [NSString stringWith ...],按照惯例,你拥有任何你调用alloc,new copy或mutableCopy的东西。你称之为的不是那些,是自动释放的。

请参阅记忆指南here。具体来说,请查看rules

获取自动释放的对象意味着它将在不久的将来某个时候消失。如果您不需要保持该函数的范围之外,那么您可以在其上调用autorelease或使用其中一种不分配的便捷方法等...

例如:

// my object doesn't need that formatted string - create the autoreleased version of it.
- (NSString) description {
    return [NSString stringWithFormat:@"%@ : %d", _title, _id]; 
}

// my object stuffed it away in an iVar - I need the retained version of it.  release in dealloc
- (void) prepare {
    _myVal = [[NSString alloc] initWithFormat:"string I need for %d", _id];
}

在第一个例子中,我为其他人创建了一个方便的方法来调用,我的类不需要超出该方法范围的那个对象,所以我创建它的自动释放版本并返回它。如果调用者需要它超出了他的调用方法的范围,他可以保留它。如果没有,他可以使用它,让它消失。代码非常少。

在第二个例子中,我正在格式化一个字符串并将其分配给我需要在我的类的生命周期中保留的iVar变量,所以我调用alloc来保留它。我拥有它并最终释放它。现在,我可以在这里使用第一个版本,并且也在其上调用retain。

答案 1 :(得分:0)

您对分配与实例方法存在根本性的误解。

第一个例子,NSDictionary的-objectForKey方法,返回id,而不是NSDictionary的实例,因此它不会分配或初始化变量。

然而,第二个是保留释放周期的经典保留部分。

这两个方法基本相同(如果我们假设数组是alloc'd但第一个是空的,第二个是nil),并且两者都获得了数组对象的所有权。我会选择第二个,因为它保证了参考,而且它更短。

我认为你对此感到困惑的是新的便利方法。方便方法(如NSNumber的+ numberWithInt:,NSString的+ stringWithFormat:和NSMutableArray的+数组)返回类的自动释放实例(通常)。 New只用一个词代替alloc和init。