Re: Memory allocation questions
Re: Memory allocation questions
- Subject: Re: Memory allocation questions
- From: Ondra Cada <email@hidden>
- Date: Sun, 28 Jul 2002 18:09:37 +0200
On Sunday, July 28, 2002, at 06:52 , Terry Simons wrote:
The ObjectiveC language all by itself doesn't seem too complicated, but I'
m confused when it comes to the memory management aspects that are part
of Apple's runtime.
Strictly speaking, memory management is not part of the runtime, but part
of the libraries (Foundation, actually). That's unimportant.
"By autoreleasing an object-that is, by sending it an autorelease
message-you declare that you don't need the object to exist beyond the
scope you sent autorelease in."
I'm assuming that scope here means essentially the same thing as in
standard C/C++?
Nope. It means the scope of the current autorelease pool, which is -- for
a normal Cocoa application without customized pools -- the event loop.
Conceptually, it's something roughly like
// NSApplication entrails
for (;;) {
get_next_event();
send_the_appropriate_message(); // like, mouseDown, keyDown, etc... all
this stuff
release_all_objects_autoreleased();
}
What *exactly* does autorelease do differently than release?
It puts the object into a list (the current autorelease pool). It does not
change its retain count.
The autorelease pool is later (again, normally at the very end of the
event loop) enumerated, and each object of it is sent -release.
Now... does this NSArray get disposed of at the end of the scope of the
function it got returned to, or does it live for the life of the
application?
It gets disposed at the end of event loop (unless someone retained it
before that).
- (void)setMainSprocket:(Sprocket *)newSprocket
{
[mainSprocket autorelease];
mainSprocket = [newSprocket retain]; /* Claim the new Sprocket. */
return;
}
My attempt at understanding the above method:
First Line:
mainSprocket needs to get autoreleased because we're going to change it's
value?
Probably right, though more precise would be that "the object which
mainSprocket points to needs to get autoreleased since we're going to
change the pointer value -- and thus won't need the object anymore".
(Why not use release instead of autorelease in this example?)
Exactly that is explained in the documentation (that's the reason the
example's there!!!).
Since it just might happen that newSprocket points to the same object as
mainSprocket, and if we released it, it just might happen that it is
deallocated immediately (if its retain count was one).
In this case, the retain at the next line would fail, since it would be
sent to the just deallocated object (more precisely, to the address where
the object has been: now there's junk, or -- in multithreaded app -- there
might be another object).
Second Line:
mainSprocket gets newSprocket, retain the contents, because the function
that passed in the data should have autoreleased it?
Right.
Again, more precisely: because the function that passed in the data should
have to ensure proper releasing of the object -- whatever it means -- by
itself.
In other words, usually the object is already autoreleased by the passing
code. Or, it might be a transient object, which lives the whole
application life and gets never ever released. Only caller knows that; you
just know that
- you just can use the object in the scope (precisely: of the current pool.
Imprecisely, but more obviously and definitely on the safe side: of the
current function/block, including a possible return statement) without any
memory management issues;
- if you want to use the object outside the scope (normally it means:
store reference to it in a global or instance variable), you have to
retain it;
- if you retained it, you have to (auto)release it when you are through
with it.
Note that this (auto)releasing might mean the object is deallocated or not:
that's outside of your control, and outside of your interest.
- (void)setMainSprocket:(Sprocket *)newSprocket
{
[mainSprocket autorelease];
mainSprocket = [newSprocket copy]; /* Get a private copy. */
return;
}
I'm assuming that mainSprocket is basically getting a copy of all of the
values stored in newSprocket?
This seems like a (sorry for likening this to another language) C++ copy
constructor. Is that a close approximation?
Ammmm.... yes and not. Do read the NSCopying documentation.
Generally, copy makes an immutable copy, let's say, a snapshot of the
object. How exactly it is done depends on the object itself: the extreme
situation is if the object happens to be immutable, in which case nothing
is copied, the object just retains itself -- its -copy is implemented this
way
@implementation ImmutableObject
-copy {
return [self retain];
}
@end
The "invariant" of -copy method is: "what you ge has the same value as the
object in this moment, and will never change". The implementation might be
simple C++-like copy, or much more trickier (and much more effective).
Ugh... this stuff makes my brain hurt.
Check Stepwise, there's a heap of great articles of this stuff.
---
Ondra Hada
OCSoftware: email@hidden
http://www.ocs.cz
private email@hidden
http://www.ocs.cz/oc
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.