【问题标题】:When and when to not allocate memory to objects何时以及何时不为对象分配内存
【发布时间】:2012-04-07 17:56:28
【问题描述】:
NSArray *array = [dictionary objectForKey:@"field"];

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

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

欢迎妈妈们详细的解释和有用的参考。

【问题讨论】:

  • 你忘记了 NSArray *array = [NSArray arrayWithArray:[dictionary objectForKey:@"field"]];而你在 [NSArray alloc... 之前忘记了 '['
  • @user1213334:已编辑,谢谢。

标签: objective-c memory-management ownership


【解决方案1】:

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

但是,如果您要问通过 alloc 获取对象与便捷方法获取对象之间的区别。 ([NSString alloc] init vs [NSString stringWith ...),按照惯例,你拥有任何你称之为 alloc、新副本或 mutableCopy 的东西。任何你称之为不是那些的东西,都是自动释放的。

请参阅内存指南here。具体看rules

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

例如:

// 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。

【讨论】:

  • 对于你的答案,我的问题是,“我什么时候应该拥有一个对象”......,希望你现在得到我的问题。
  • 我用例子更新了它。当您需要该对象超出该函数的生命周期时,您应该拥有它(通过分配或调用保留)。
  • 拥有它的经典例子是当你创建一些东西并将它分配给一个 iVar(成员变量),然后在该对象的生命周期内被多个方法使用。当对象被释放时你释放它。
  • 如果您创建一个要返回的数组(并且您的类在该便捷方法的范围之外不需要它)然后使用自动释放方法创建它。让被叫者决定他是否需要拥有它。
  • 如果调用者得到它,在他的方法中使用它并且在他的调用方法之外不需要它,他不会保留它。在未来的消息循环中,它将消失,这两种方法都不需要保留和内存管理代码。
【解决方案2】:

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

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

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

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

我认为您对此感到困惑的是新的便捷方法。方便的方法(如 NSNumber 的 +numberWithInt:、NSString 的 +stringWithFormat: 和 NSMutableArray 的 +array),返回类的自动释放实例(通常)。只需一个词,new 就取代了 alloc 和 init。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-30
    • 2021-04-01
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多