简体   繁体   中英

Memory management in objective-c

I have this code in one of my classes:

- (void) processArray
{

   NSMutableArray* array = [self getArray];
   . . .
   [array release];
   array  = nil;
}


- (NSMutableArray*) getArray
{
   //NO 1:
   NSMutableArray* array = [[NSMutableArray alloc]init];

   //NO 2:
   NSMutableArray* array = [NSMutableArray array];
   . . .
   return array;
}

NO 1: I create an array and return it. In the processArray method I release it.

NO 2: I get an array by simply calling array . As I'm not owner of this, I don't need to release it in the processArray method.

Which is the best alternative, NO 1 or NO 2? Or is there a better solution for this?

The method should return an autoreleased array, NO 2 is the better choice. The reason for this is that when you call the method with

   NSMutableArray* array = [self getArray];

you will expect as a matter of convention to not have to release the array. If you want to take ownership of it, you retain it, but otherwise you shouldn't have to care about it. In Cocoa, you only take ownership by explicitly sending alloc or retain or copy (or new ). Since the processArray method doesn't do that, it shouldn't have to take care of releasing the array.

So you should use NO 2, and also you should remove these two lines:

[array release];
array  = nil;

If the array and its contents use a lot of memory or its used lots of times, you'll want to release them straight away, so use option 1. According to the Objective-C guidelines, you'll want to prefix the word "new" to your subroutine name instead of "get" in that case.

If on the other hand, you want to reduce the number of lines of code that say simply [array release]; or similar then use option 2.

It is simply a balance between reducing lines of code, and reducing unnecessary temporary memory use.

Whilst the autorelease pool will help in reducing memory leaks and make your code smaller, sometimes you need to explicitly release everything as it goes out of use to keep the use of memory down.

HTH

EDIT

Ah - I stand corrected. Reading the iPhone version of the Memory Management Programming Guide for Cocoa I see that the iPhone guidelines are to use a prefix of "new..." so for example "newArray" in this case, if the caller is supposed to manually release and NOT a prefix of "create...". "Creating" can refer either to creation of manually released or of automatically released objects and so would be ambiguous. Text corrected above.

- (void) processArray
{

   NSMutableArray* array = [[self getArray] retain];
   //Now you are the owner of array, so you take care to release it

   . . .

   [array release];
   array  = nil;
}


- (NSMutableArray*) getArray
{
   //create a new array 
   //temporarily the method owns the array
   NSMutableArray* array = [[NSMutableArray alloc]init];

   //fill in here with elements or what you want
   ..........

   [array autorelease];
   //autorelease here says "I don't own the result
   //if anyone cares about it, he should retain it himself

   return array;
}

So in short when you create new objects you should autorelease them before returning. Because if the calling method wants to use the result, the calling method should take care of retaining and releasing the result.

It's always good to run the Klang static analyzer for this issues, when you are not really sure in your retaining/releasing code : http://clang-analyzer.llvm.org/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM