Re: Memory Management
Re: Memory Management
- Subject: Re: Memory Management
- From: Nat! <email@hidden>
- Date: Tue, 29 Jul 2003 20:23:50 +0200
Am Dienstag, 29.07.03 um 17:01 Uhr schrieb Marco Scheurer:
On Monday, July 28, 2003, at 09:50 PM, Fritz Anderson wrote:
On Monday, 28 July 2003, at 1:44 PM, Marcel Weiher wrote:
On Monday, Jul 28, 2003, at 01:20 Europe/London, Martin Haecker
wrote:
...
- (NSString *)name
{
return [[_name retain] autorelease];
}
Although there has been some championing of this method by
well-placed individuals, their preference has not met with an
overwhelmingly positive response, to say the least. IMNSHO, their
case, although appealing at first, has been thoroughly debunked and
is not widely supported by the Cocoa community any longer. Of
course, you may disagree with this view, but at the very least the
statement that this is the preferred method is highly controversial.
You surprise me. I once ran into a string-processing method in
OmniFoundation which, in no-op cases, returned its internal storage.
Consider the following code:
NSString * result = [ofProcessingObject processedString];
[ofProcessObject release];
NSLog(@"The result is %@", result);
I am entitled to assume that result has not been disposed-of, am I
not?
I share Marcel's views on this subject. We wrote an article which
shows why we think that this pattern is a bad thing. It will hopefully
be published soon.
This pattern is obviously an attempt to fix in -processedString a
problem that is caused by = .
The problem is not caused by =.
In other environments the assignment would prevent result from being
freed during the lifetime of the variable. Since it cannot be done
here the "solution" is too extend a little bit the lifetime of objects
so that it works a little bit more like a garbage collected
environment.
This is thinking in another language, and forcing Foundation /
Objective-C into that mindframe. It doesn't help putting "garbage
collection" as a concept or a goal to be aspired to, into this mail
thread.
Now consider the following code:
- doSomething
{
result = [ofProcessObject processedString];
[ofProcessObject release];
[self doSomethingElse];
}
- doSomethingElse
{
NSLog (@"The result is %@", result);
}
Shouldn't I also be able to claim that I am entitled to assume that
result has not been disposed-of? Why not? And what about the > following?
- doSomething
{
result = [ofProcessObject processedString];
[ofProcessObject release];
[self performSelector:@selector(doSomethingElse) withObject:nil
afterDelay:0.0];
}
- doSomethingElse
{
NSLog (@"The result is %@", result);
}
Obviously, the similarity to a garbage collection is limited. Will
everybody stop claiming that result should not have been released in
every case?
Autorelease pools have some clear semantics. Every object added to an
autorelease pool gains a property, a guaranteed minimum lifetime. Not
more not less. Autorelease therefore guarantees (if result is
autoreleased) that your case 1 will work and also guarantees that case
2 has a high chance of failure.
I wrote a lot of stuff here <now deleted>, and needed to look up
something in the documentation, lo and behold:
http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/
index.html#//apple_ref/doc/uid/10000011i
contains basically everything I wanted to write.
What I'd like to add is this. Sharing a return value between caller and
method ideally should be fail safe. To be fail safe the returned value
must be under ownership of the caller. With ownership I mean, that the
value can be read (or written to, if possible) at the callers
convenience.
For those int, double return values it's trivial, because the value is
copied through registers or stack. If there is memory involved then
there needs to be a clear protocol for the transfer or sharing of that
memory. If the memory is owned by the caller, then there is no problem,
the caller temporarily grants read/write access to its memory area, and
can peruse it at will on return:
- (void) getName:(NSMutableString *) s
{
[s setString:name_];
}
this is ideal and fail safe. It is not done, because it is deemed to
cumbersome. The caller must create temporary objects and release them.
If the memory is solely owned by the method (instance), this means a
weakening in the fail-safeness
- (NSString *) name
{
return( name_);
}
This transfers a pointer to memory, not owned by the caller. If name_
gets set to something else as a side effect to another call to that
instance, I can expect crashes, because the previously returned value
might now point to invalid memory. This method provides therefore only
a limited kind of read access to the return value. That limited access
says, you may access that value, if you know, that it hasn't changed in
the mean time. (In 99% of all cases, I think you will be able to say,
yes I can do that :), otherwise you'd have problems using
NSMutableArrays)
If I code something like this:
- (NSString *) name
{
return( [name_ retain]);
}
I am sharing ownership with the caller. (If name_ is immutable, I am
sharing read access completely.) This would be the proper thing to do,
alas it is not Foundation like, because the need for the caller to
release all accessed objects would also be too painful to code. The
Foundation way to achieve almost fail safeness is to provide the caller
with [... retain] autorelease] a return value, which gives full read
access during the scope of the callers(!) autorelease pool.
The reason why you get these funny problems when name_ is mutable is,
because you are not yielding access completely, the contents are still
subject to change by the messaged instance. That's why using copy]
autorelease] would be proper, as it also gives the full access rights
of the return value contents to the caller (within the scope... bla
bla).
I am not promoting the use of retain] autorelease] (I dislike slowness
:)), but I don't mind it to be the documentation default. What I
dislike is the dogmatic "you must code like this". Fortunately I see
nothing like this in the Apple dox.
Ciao
Nat!
------------------------------------------------------
But didn't I always tell you, honey, if I just stayed
in place and I never spoke up, good things are bound
to happen ? -- Jonathan Gems
_______________________________________________
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.