3

当实例方法返回一个使用便利构造函数初始化的值时,我是否需要保留该对象,然后在返回中自动释放,以便当便利构造函数的自动释放发生时,它不会删除该对象。

是否会在调用代码之前发布描述并通过保留或其他方式获取所有权?

- (NSStringMutable *)test {
    NSMutableString *description = [NSMutableString stringWithString:@"Test Value"];
    return description;
}

还是应该这样?

- (NSStringMutable *)test {
    NSMutableString *description = [NSMutableString stringWithString:@"Test Value"];
    [description retain];                               
    return [description autorelease];
}

调用代码:

NSMutableString *testVar = [[NSMutableString alloc] initWithString:[object description]];
4

5 回答 5

10

不,你应该没问题:

- (NSStringMutable *)test
{
    return [NSMutableString stringWithString:@"Test Value"];
}

这将使对象的保留计数为 1,并将位于自动释放池中。

自动释放池在特定时间耗尽 - 它不像垃圾收集器。如果您正在实现一个事件处理程序(如按钮单击处理程序),当您从事件处理代码返回时,框架会耗尽自动释放池。

如果你用过这个:

- (NSStringMutable *)test
{
    NSMutableString *description = [NSMutableString stringWithString:@"Test Value"];
    [description retain];                                                               
    return [description autorelease];
}

...然后该对象的保留计数为 2 并且将在自动释放池中两次,并且实际上的行为方式与前面的代码示例中的方式相同。

于 2009-08-12T15:02:24.953 回答
1

你可以退货。这是自动释放的主要目的之一。除非您设置了自己的自动释放池,否则池在下一次运行事件循环之前不会被耗尽。内存管理编程指南详细解释了所有这些——你应该阅读它,直到你感觉舒服为止。

旁注:如果这不安全,并且自动释放池由于某种奇怪的原因会提前耗尽,那么给它两个保留和两个自动释放不会有什么不同。数字仍然是平衡的,所以它仍然会在某个时候被释放出来。

于 2009-08-12T15:03:06.870 回答
1

我已经对正确答案进行了投票,我将其添加为样式说明:

您的调用代码不起作用,因为它[object description]在应该调用的时候调用[object test]

除非您真的希望能够更改字符串,否则您不需要返回可变字符串。我个人尽量减少我编写的代码中的可变性,因为我觉得维护状态变化最小的程序更容易。您只返回一个描述,所以我认为它不需要是可变的。我知道这只是一些示例代码,所以也许我太挑剔了

您可以将其重写为:

-(NSString *)description {
    // Just return a static NSString. No need to worry about memory management.
    return @"Test Value";
}

如果您希望能够在调用代码中更改此返回字符串的值:

NSMutableString *testVar = [[NSMutableString alloc]initWithString:[object description]];

由于您已经在此字符串上调用了 alloc,因此您拥有它并负责在将来的某个日期释放它。

或者,您可以使用我最喜欢的代码之一:

NSMutableString *testVar = [[object description] mutableCopy];

这甚至会返回一个不可变对象的可变副本(当然,如果它符合 NSMutableCopying 协议)。你需要[testVar release]在某个阶段发送。

并将其作为对您问题的实际答案:如果您向对象发送alloccopymutableCopyretain,那么您拥有该对象并负责向其发送发布消息。你可以假设其他任何东西都会返回一个自动释放的对象。

同样,我知道这只是您提出问题的一小段示例代码,但如果您遵循上述规则,您的大部分内存管理问题都会得到解决。在您的第一个示例中,您没有发送任何这些消息,因此您不需要自己释放任何内存。但是,您alloc的调用代码中有一个,因此您拥有testVar并且需要释放它。

于 2009-08-12T15:37:38.927 回答
0

不,您可以简单地返回自动释放的值。这样做的原因是 autorelease 不是变量本身的函数,它是 autorelease 池的函数,它(除非你自己创建一个)通常由运行循环管理。

于 2009-08-12T14:59:47.640 回答
0

您与第二个很接近,但是对于您在这里谈论的情况,您不需要保留,实际上也不需要自己调用 autorelease 。

这是有效的,因为 stringWithString 将返回一个自动释放的对象:

 - (NSStringMutable *)test
 {
   return [NSMutableString stringWithString:@"Test Value"];        
 }

通常,如果您调用便利构造函数(而不是调用 alloc 和 init),则使用 Objective-C 创建对象时,返回值始终是自动释放的,因此 stringWithString 返回一个自动释放的对象,您可以直接返回。

于 2009-08-12T15:02:38.790 回答