你是否释放了函数中返回的对象?

时间:2011-09-23 02:26:55

标签: iphone memory-management

这是针对使用Xcode 4在Objective-C中编写的iPhone APP。

快速的问题是,如果你有一个返回NSArray的函数,该函数在该函数中是ALLOC,你是否必须释放它?

以下是更详细的问题。

我在我的iPhone应用程序上运行“Analyze”并且它抱怨我的某个功能可能存在内存泄漏

该函数从NSMutableArray中创建一个NSArray并返回NSArray。我正在做的是获取类对象的NSMutableArray并从中创建NSStrings的NSArray。我已经尽可能地简化了代码以显示问题所以如果它看起来没有做任何有用的事情,请不要担心。

-(NSArray *)encodeArray
{
    // I use a NSMutableArray here because I do not know how big the starting
    // array will be (I hard coded the 20 here for now)
    NSMutableArray *tmp = [[NSMutableArray alloc]init ];

    for (int y = 0;y<20;y++) {
        // create the NSString object and add it to the tmp array
        NSString *cardcount = [NSString stringWithFormat:@"%i%",y];
        [tmp addObject:cardcount];
    }
    // create the array we will be returning out of the NSMutableArray
    NSArray *array = [[NSArray alloc] initWithArray:tmp copyItems:YES];
    // release the tmp array we created.
    [tmp release];

    // return our array
    // This is the location of the potential memory leak.  SHOULD I RELEASE THIS
    // If I DO - HOW DO I RETURN IT.
    return array;
}

我需要释放阵列吗?如果是这样,我怎么还能回来呢?也许有更好的方式来完成我正在做的事情?

总体目标是创建一个NSArray,以便我可以使用NSUserDefaults来保存应用程序状态。

2 个答案:

答案 0 :(得分:3)

通常,您希望在这种情况下返回自动释放的数组。如果您在函数中释放它,它将在您的调用者有机会保留自己的副本之前被释放。如果你不自动发布它,那么当你的调用者保留返回的对象时,你的保留计数为2,并且很可能会泄漏。

所以,只需将你的return语句更改为:

return [array autorelease];

答案 1 :(得分:1)

根据经验;如果你(通过我的意思是对象的当前范围)保留/复制/等一个对象,那么你必须在某处释放/自动释放它。由于呼叫encodeArray的人没有对array进行保留,因此他们不负责释放它。因此,需要在返回之前将其设置为自动释放:

-(NSArray *)encodeArray
{
    // I use a NSMutableArray here because I do not know how big the starting
    // array will be (I hard coded the 20 here for now)
    NSMutableArray *tmp = [[NSMutableArray alloc] init];

    for (int y = 0;y<20;y++) {
        // create the NSString object and add it to the tmp array
        NSString *cardcount = [NSString stringWithFormat:@"%i%",y];
        [tmp addObject:cardcount];
    }

    // create the array we will be returning out of the NSMutableArray
    // Named initializers indicate that the object will be autoreleased:
    NSArray *array = [NSArray arrayWithArray:tmp];

    // release the tmp array we created.
    [tmp release];

    // return our array
    return array;
}

或者:

-(NSArray *)encodeArray
{
    // I use a NSMutableArray here because I do not know how big the starting
    // array will be (I hard coded the 20 here for now)
    NSMutableArray *tmp = [[NSMutableArray alloc] init];

    for (int y = 0;y<20;y++) {
        // create the NSString object and add it to the tmp array
        NSString *cardcount = [NSString stringWithFormat:@"%i%",y];
        [tmp addObject:cardcount];
    }
    // create the array we will be returning out of the NSMutableArray
    NSArray *array = [[NSArray alloc] initWithArray:tmp];

    // release the tmp array we created.
    [tmp release];

    // return our array
    return [array autorelease];
}