Search code examples
iphoneobjective-cmemorymemory-managementalloc

IPhone Objective C Memory Allocation


I understand that when using Alloc, new or copy you own the object and need to release the object. I understand that if I retain an object that I need to release it.

But if I have the following statment at the end of a method:

return [[UIImage alloc] initWithContentsOfFile:path];

I own the UIImage object becaused I allocated the memory space, but I dont have a reference to it anymore because it was returned to the caller. In my dealloc() method I can't release it, since I dont have a reference.

So my question is, is this correct:

return [[[UIImage alloc] initWithContentsOfFile:path] autorelease];

I beleive in this case the caller then can retain the returned object if they like to take ownership and will eventually need to release themselves.

Thanks for your help.


Solution

  • The whole point of autorelease was built around returning objects.

    - (id)bad {
        MyObj *obj = [[MyObj alloc] init];
        return obj;
    }
    

    This code returns everything correctly, but you (as developer) must be sure to release the object later on.

    - (id)moreBad {
        MyObj *obj = [[MyObj alloc] init];
        return [obj release];
    }
    

    This code uses the memory as expected, balancing retain and release in one scope, but returned object is garbage now (expect this to crash).

    - (id)good {
        MyObj *obj = [[MyObj alloc] init];
        return [obj autorelease];
    }
    

    This code is "delayed release". I.e. you can retain the object at the caller side and the object would be safe. It could surely be broken if you don't have NSAutoreleasePool in scope, but that's a pretty rare condition, and you mostly know when that happens (the most common scenario is to start a new thread where there is no "default" autorelease pool).

    So, the common practice is to balance the retain (and retain-like) and release methods in one scope. Next suggestion is to always have objects alloc-init-autoreleased, and switch to distinct releases if you have memory issues (like autoreleasing lots of objects in a loop). Next suggestion is to switch to ARC.