Rob
Rob

Reputation: 4139

iPhone Memory Debugging

I'm using Instruments to try to determine if there are places in my application that I could be more efficient with use of memory. I've taken the time to get somewhat familiar with Instruments but I'm generally a newbie with hunting memory management issues having come from a Java background. I seem to be using about 1.82mb by calls to this method:

+ (NSString *)stringFromDateWithFormat:(NSDate *)date withFormat:(NSString *)format
{
    NSDateFormatter *dateFormatter;
    NSString *result;

    if (nil == date || nil == format)
        return nil;

    result = nil;
    if (nil != (dateFormatter = [[NSDateFormatter allocWithZone:[self zone]] init])) {
        [dateFormatter setDateFormat:format];   

        if (nil != (result = [dateFormatter stringFromDate:date])) {
            [dateFormatter release];
            return result;
        } 

        [dateFormatter release]; 
    } 
    return nil;
}

As I'm releasing the date formatter I'm wondering if the NSString result is my issue. It seems to me that the stringFromDate library call would return an autoreleased object so there's nothing I can do to 'manually' manage it. A bit unsure of how to optimize this method.

Upvotes: 1

Views: 2023

Answers (3)

Tony
Tony

Reputation: 3478

Is this method getting called a lot of times in a loop? Autoreleased objects only get released when the NSAutoreleasePool they're in gets released. As I understand it, the default autorelease pool is created and release every event loop. It's possible you're creating too many autoreleased objects in the course of a single event loop. The solution is to create your own NSAutoreleasePool in an appropriate place, and release it to clear up autoreleased objects. An extreme example that illustrates the point:

int i;
NSAutoreasePool* pool = nil;
for (i = 0; i < 1000000; ++i) {
    /* Create a new pool every 10000 iterations */
    if ((i % 10000) == 0) {
        if (pool) [pool release];
        pool = [[NSAutoreleasePool alloc] init];
    }
    [someObj someMethodThatCreatesAutoreleasedObjects];
}
[pool release];

In that example, the current pool is released every 10,000 iterations and a new one is created. You can read more about memory management in the Memory Management Programming Guide section on autorelease pools.

Upvotes: 4

J.J.
J.J.

Reputation: 4872

I am not a 100% with this. I am also just learning Mac/Iphone development. But you can use the auto release pool to help with memory management. It is used to get around release problems.

Here is an article with lots on memory management. Check out the left sided menu.

Upvotes: 0

Marc Charbonneau
Marc Charbonneau

Reputation: 40513

You need to return an autoreleased object anyway, so there's really nothing you should be doing about the result string. I don't see any mistakes related to memory, but your code is definitely more verbose than needed. Keep in mind that in Objective-C, if you call a method on nil, you get back nil (or 0 for an integer, but not for floating point values). You can take out all those if statements and the two return paths, and your code will still work the same way. Also, I would just use alloc instead of allocWithZone.

Upvotes: 0

Related Questions