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];
}
精彩评论