我应该始终复制还是保留从函数返回的字符串

时间:2012-03-05 16:36:43

标签: iphone objective-c cocoa-touch

我是否应该始终保留或复制从函数返回的字符串值?

请考虑以下示例:

- (NSString*) getString:
{
    return [[NSString alloc] autorelease];   
}

- (NSString*) getStringAlloc:   // Not sure if this convention is correct 
{
    return [NSString alloc];   
}  

...

在调用方法

NSString* myString = [self getString];

如果我想继续在函数中使用myString而不释放它我该如何处理它。也是使用正确约定的第二种方法的名称。

如果我知道返回的字符串是自动释放的(从方法名称)并且它没有被更改,那么可能保留或复制的唯一原因是因此有人未来不会更改代码。如果我不介意价值改变那么,我可能不需要保留或复制。

假设我没有使用ARC。

4 个答案:

答案 0 :(得分:3)

没有!创建对象的范围(在这种情况下,您的方法“getString”)也负责释放它!所以第一种方法是唯一有效的方法。

此外,按照惯例,getter-methods不以“get”为前缀。因此,应该将该方法称为- (NSString*) string

答案 1 :(得分:1)

你的约定是C ++,但是如果你要使用Cocoa,你可能也就是Cocoa。使用init,get,set作为方法的前缀在Objective C中具有特殊含义,因此了解它们非常重要。

基本上,如果您创建一个NSString,它将被保留(即您使用init函数创建它)或自动释放(即您使用名称中没有init或copy的方法创建它)。如果它是自动释放的,你可以在函数中使用它直到函数结束,然后它将在将来的某个时候发布。如果保留,则必须将其释放。 ARC将为您管理此问题,但您仍需要了解iOS内存管理的基础知识才能获得成功。你真的需要阅读:

Apple Memory Mangement Guide

答案 2 :(得分:1)

如果使用自动释放,则在“最内层的嵌套自动释放池将耗尽”之前,不会释放您的字符串。如果您曾创建过自动释放池,则很可能不会读取此内容,因此我们假设我们拥有系统的自动释放池。当它没有任何其他事情要做时,它会耗尽它们(即删除标记为自动释放的对象),但总是在事件周期结束时。这意味着如果将autorelease对象分配给局部变量,则可以确保它将保留在局部变量的整个范围内。但是,当您将autorelease变量分配给类成员时,您应该注意,在这种情况下,它可以被删除,直到您下次访问它。避免这种情况的最佳方法是使用保留类型属性。

答案 3 :(得分:1)

首先,如果可以的话,你应该使用ARC。 ARC使大部分内存管理远离开发人员。我说的最多,而不是全部,因为如果你使用的是Core Graphics框架,你必须自己发布这个对象。

您还应该考虑对NSString对象使用autorelease重载,如下所示:

NSString *someString = [NSString stringWithFormat:@"Hello World"];

NSString stringWithFormat方法将返回一个自动释放的对象。