Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa Touch Question. Should [NSMutableArray array] be retained?

Here is the gist of some code I'm writing. I'm concerned that I am not properly addressing the retain/release issues with the array class method on NSMutableArray. Is the following actually leaking memory?

for(a while) { 
    // do stuff
    NSMutableArray *a = nil;
    // do stuff
    if (!a) {
        a = [NSMutableArray array];
    }
} // for(a while)
like image 970
dugla Avatar asked Nov 30 '22 12:11

dugla


2 Answers

You wouldn't leak memory in this code, and releasing the array yourself will cause a crash when the array is autoreleased at the end of the run loop.

Most Cocoa classes provide a couple of ways of making a new object, and are very consistent with this convention:

  1. [[NSSomeObject alloc] init] : you are responsible for releasing the object (instance method).

  2. [NSSomeObject someObject] : the object will be autoreleased for you, usually at the end of the run loop (class method). It's roughly equivalent to [[[NSSomeObject alloc] init] autorelease].

The proper use of the instance method would be:

a = [[NSMutableArray alloc] init];
// do stuff
[a release];

The proper use of the class method would be:

a = [NSMutableArray array];
// do stuff, array is in the autorelease pool

Note that Apple has recommended you stay away from the convenience methods as much as possible to improve performance. This is controversial advice, may not save much processor time, and separates the alloc-init from the release on an object you may not actually care much about keeping.

like image 78
Ryan McCuaig Avatar answered Dec 05 '22 02:12

Ryan McCuaig


From the Cocoa Memory Managment Rules:

You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.

Therefore with the line:

a = [NSMutableArray array];

you do not take ownership of the array, and it will be passed to you autoreleased. The memory will be handled for you automatically by the autorelease pool, and once it is no longer being used, it will be released for you. If you want to keep the array outside the current event, however, you must retain it, otherwise it will be released for you.

like image 33
Alex Rozanski Avatar answered Dec 05 '22 00:12

Alex Rozanski