开发者

Do you release the object which is being returned in a function?

This is for an iPhone APP written in Objective-C using Xcode 4.

The quick question is if you have a function which returns an NSArray which was ALLOC'ed in that function, do you have to release it?

Here is the more detailed question.

I run "Analyse" on my iPhone app and it complains about a possible memory leak on one of my functions

The function creates a NSArray out of a NSMutableArray and returns the NSArray. What I am doing is taking an NSMutableArray of class objects and creating an NSArray of NSStrings out of them. I have simplified the code as much as possible to show the problem so don't worry if it looks like its not doing anything useful.

-(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;
}

Do I need to release the array? If so, how can I still return it? Maybe there is a better way to perform what I am doing?

The overall goal is to create a NSArray so that I can use the NSUserDefaults to save the application state.


Typically, you want to return an auto-released array in this case. IF you release it in your function, it will be deallocated before your caller has a chance to retain its own copy. If you don't autorelease it, then when your caller retains the returned object you will have a retain count of 2, and it is likely to leak.

So, just change your return statement to this:

return [array autorelease];


As a rule of thumb; if you (by you I mean the current scope of the object) retain/copy/etc an object, then you must release/autorelease it somewhere. Since whoever calls encodeArray didn't do the retaining on array, they are not responsible for releasing it. Therefore, it needs to be set to be autoreleased before being returned:

-(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;
}

Or:

-(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];
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜