iDevGames Forums
Objective C memory management - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Game Programming Fundamentals (/forum-7.html)
+--- Thread: Objective C memory management (/thread-1037.html)



Objective C memory management - Madrayken - Jul 10, 2009 06:09 AM

Okay, code question of the week:

Code:
NSString *file = [[NSString alloc] initWithContentsOfFile: filename_with_path encoding: NSASCIIStringEncoding error: NULL];
        file = [file stringByReplacingOccurrencesOfString:@" " withString:@""];        // Strip out spaces
        file = [file stringByReplacingOccurrencesOfString:@"\t" withString:@""];    // Strip out tabs

According to XCode, I don't have to release 'file' at the end, because at this point, it's an autoreleased element created by a convenience constructor. So... what happens to the original alloc-ed NSString's memory?

Any help much appreciated.


Objective C memory management - daveh84 - Jul 10, 2009 07:40 AM

Class methods are autoreleased by default, initialization methods are not.

So what you are doing when you make your 3 assignments to the single variable file is pointing the same variable to 3 different locations in memory.

All local variables need to be autoreleased, and this is a perfect example of why. Your first initialized file is retained indefinitely, as there is no way to find and release the memory it used (until the application exits).

Put an autorelease at the top (or, preferably, use the class method stringWithContentsOfFile:, if it exists).


Objective C memory management - Madrayken - Jul 10, 2009 09:02 AM

Aha! Thanks, thought as much.

In general, I'm trying not to rely on Autorelease if at all possible. I've now changed my code so it's:

Code:
NSString *original_file = [[NSString alloc] initWithContentsOfFile: filename_with_path encoding: NSASCIIStringEncoding error: NULL];
NSString *file = [original_file stringByReplacingOccurrencesOfString:@" " withString:@""];        // Strip out spaces

[original_file release];
file = [file stringByReplacingOccurrencesOfString:@"\t" withString:@""];

That way, there's one Initialisation method, and two Class methods, but I have sufficient control over the original_file to be able to get rid of it.


Objective C memory management - DoG - Jul 10, 2009 10:13 AM

daveh84 Wrote:Class methods are autoreleased by default, initialization methods are not.

That isn't really true, and a very sketchy definition to go by. The docs are pretty clear about this though:
Quote: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.

Only the first of the three lines contains an alloc, so that should be (auto)released, the other two lines are convenience methods and return autoreleased objects which you don't have to worry about.

Either put a file = [[...] autorelease]; on the first line, or use +stringWithContentsOfFile: to get the string instead of +alloc/-initWith... .