The details of memory management take a long time to understand fully, but there are some basic simple principles that will really help you out.

1. When you get an object from a method that starts with "alloc" or "new", or contains the word "copy" in it, YOU own that object. The retain count will be 1, (conceptually anyway), that is, no one else knows about it unless you want to share that object with other code.

2. Any other method that creates a new object that does not use the words described above (alloc, new, copy), returns to you an object that basically no one owns, it's been added to the auto-release pool. So if you do not claim ownership by issuing a retain, that object will be deallocated during the next autorelease pool cleanup. If you're just creating and using the object in a method and your object has local scope and you don't care about holding on the the object after the method ends, then you don't have to do anything, the object will be automatically freed. However, if the object needs to survive the local method, if other methods are going to be called later that need to have access to that object, you need to claim ownership by issuing a retain.

In your example you create an NSArray by calling arrayFromObjects. There is no "alloc", "new", or "copy" in that method name, so this new object now referenced by "a" is autoreleased. If that's what you want, do nothing. If the abject referenced by "a" needs to live when the method ends, you need to call retain. However, this *specific* example of yours complicates things, because the method itself is an object creation method. Your method name is "makeObject", which does not contain the magic words, so any Cocoa user calling your method is going to expect the object they get back is autoreleased. In this *specific* example of yours, calling retain on it actually would break the convention.

As to what you should do in useObject, by convention you expect that "local" references an autoreleased object. What happens next regarding "local" totally depends on the contract of your MyObj class' initWithArray method. Does it state it retains the array? If so, you don't need to do anything if you don't care about "local" after this method ends. If you do care, you must retain it. If for some weird reason MyObj's documentation states that it does not retain the argument array, I would say that is bad design, but if that's what the documentation stated, then if you didn't retain it, the MyObj instance in "o" might end up holding a reference to a deallocated object after the next autorelease purge.

And since you've created your MyObj instance "o" with one the of the magic words (alloc), YOU own it. You must manage its life-cycle, or it will never be deallocated. Since this method as written is returning void, no one else cares about this object. The method ends without releasing or autoreleasing "o", so as written you have a memory leak, since "o" will never be deallocated.



Rob Ross, Lead Software Engineer
E! Networks

---------------------------------------------------
"Beware of he who would deny you access to information, for in his heart he dreams himself your master." -- Commissioner Pravin Lal



On Jun 27, 2008, at 1:22 PM, Paul Archibald wrote:

Comrades:

I have experimented a bit with this, and I think I have something that works, but I would like to understand it better. I am reading the Hillegass book, but I don't really see an example of what I am tryng to do, although it seems like a very basic question.

The Question:
If I want to create an object and pass it to another method, where I plan to use it briefly (as a local variable), what is the proper way to allocate and deallocate the object in the various methods?


Here is a simple example:

-(NSArray*) makeObject {
NSArray *a = [NSArray arrayFromObjects];someObject, anotherObject, nil];
        // should I [a retain];
        // or [a release];
        // or [a autorelease];
        // or do nothing
        // before I
        return a;
}

-(void) useObject {
        NSArray *local = [self makeObject];
        // should I [local retain];
        // or [local release];
        // or [local autorelease];
        // or do nothing
        // before I exit this method?
// I need to pass local as an argument to the creation of another object before exiting
        MyObj *o = [[MyObj alloc] initWithArray:local];
}


There are a lot of possible combinations here, and I have tried a bunch of them. Some of them work, others crash the program with a EXC_BAD_ADDRESS. But, as I have been trying to make an exhaustive test of what "works" and what "crashes", I realize that just experimenting with this is not enough, and I need a better theoretical understanding of this stuff. If you recognize this pattern and can tell me where to read more on it, that would be great, too.
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/rob.ross%40gmail.com

This email sent to [EMAIL PROTECTED]

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to