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]