Re: Memory Management (Part I)
Re: Memory Management (Part I)
- Subject: Re: Memory Management (Part I)
- From: Nat! <email@hidden>
- Date: Thu, 31 Jul 2003 00:34:38 +0200
- Resent-date: Fri, 1 Aug 2003 00:55:23 +0200
- Resent-from: Nat! <email@hidden>
- Resent-message-id: <00C7461A-C2DE-11D7-A963-003065A29EFC@mulle-kyberneti k.com>
- Resent-to: email@hidden
original posting is stuck, coz it's to big, so here it's again in two
parts..
enjoy or suffer :)
[I don't comment on everything, where I think you're just rewording
what I wrote :)]
Am Mittwoch, 30.07.03 um 22:16 Uhr schrieb Marcel Weiher:
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.
Where on earth did you get that from?!? Reference counting is a form
of garbage collection. It isn't a perfect form of garbage collection
because it can't handle cycles, but it still is a form of garbage
collection. Retain/release, of course, is not fully automatic garbage
collection, because it is at best semi-automatic.
The previous poster states that it is done to "work a little bit more
like a garbage collected environment", then I am saying: Don't think
about garbage collection, just think in terms of autorelease pools. It
doesn't help to expand the domain, then get certain amounts of
expectations going, that it oughta be doing this and that and then be
disappointed, when it fails. Read the sentence in context with the
previous discusssion, it will make sense.
Anyway, all this is only necessary when the callee does not hang on to
the object. If the callee does hang on to the object, there simply is
no *need* to extend the life of the object.
[examples]
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
It guarantees no such thing.
See my other post just before this one. It does guarantee it.
Otherwise I am really curious how you are going to "break" this
- doSomething
{
result = [ofProcessObject processedString];
[ofProcessObject release];
[self doSomethingElse];
}
- doSomethingElse
{
NSLog (@"The result is %@", result);
}
when processedString returns with "retain] autorelease]".
and also guarantees that case 2 has a high chance of failure.
Ditto.
Well lets do case 1 first :)
What I'd like to add is this. Sharing a return value between caller
and method ideally should be fail safe.
There are several levels to this statement.
At the most general level you are asking for referential transparency,
something you are never ever going to get in an imperative language,
and Objective-C is always going to remain an imperative language.
However, I think it is very good that you did bring it up in this
generality, because I think that this is the (somewhat hidden)
motivation behind some of the things that are being said. I find this
motivation understandable, because referential transparency is a nice
thing to have. However, the only way to actually get referential
transparency is to have a language designed from the ground up to
support it. It is one of these things that you absolutely cannot bolt
on to a language after the fact. How this usually works is that there
are *no* references whatsoever, only values. So there can never be
aliasing of pointers/references because there are no
pointers/references. Conceptually, everything is copied all the time.
So if you insert an element into a collection, a new collection is
created that has the element inserted at the right spot. The old
collection is not modified. Nothing is ever modified.
I ain't asking for nothing here :), I am pretty much completely happy
with Objective-C as it is, because I can achieve what you call
"referential transparency" _if_ _I_ _want_ _to_. But in many cases I am
very happy that the language doesn't force me to do that. That's why
you and me aren't coding Java (except for money) :)
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.
It isn't really the memory that is a problem. It is references to
values (vs. values) and the aliasing that can happen when you are
allowed to have more than one reference to a value.
This is just the same. The references always point to memory. Within
that memory there can be references to other memory areas (*). If
memory is deeply copied and owned by the caller then he has full
ownership. There is nothing added by calling the memory object.
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_];
}
Yes. However, I think you are forgetting that we are dealing with
objects. Just as it is valid for one method to grant access to its
'memory area' to another method, it is just as valid for one *object*
to grant access to its 'memory area' (instance variables) to another
object.
I am afraid you don't follow my argument here. I was at that paragraph
exactly just talking about the caller providing the memory, not the
other way round (that's for later). Calling it object instead of memory
doesn't make it any different, more complex maybe, yes.
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.
It is not fail-safe, but it is cumbersome.
According to my discussion, it is fail safe. The memory area was
provided for the method as a return value. If the method chooses to
retain it, it's breaking the contract. It's equally breaking the
contract if it does memset( s, 0, 16) on it.
If the memory is solely owned by the method (instance), this means a
weakening in the fail-safeness
I don't agree with this. It is sharing, just like your other case,
except that it is the *object* doing the sharing, not the method.
Well looking from the caller (and that is the way I am looking at it in
this discussion) it is, because the caller must know that the return
value is tied to the life and state of the called instance. (see below)
- (NSString *) name
{
return( name_);
}
This transfers a pointer to memory, not owned by the caller.
In the first case, you also transfered a pointer to memory, from the
caller to the callee. This is just as unsafe because the callee could
have released the memory. There is no difference!
Yeah could have, but that's "make pretend". The callee could also
memset the stack...
See how neatly the first case avoids the problem here:
- doSomething
{
NSMutableString result;
result = [[NSMutableString alloc] init];
[ofProcessObject getProcessedString:result];
[ofProcessObject release];
[self doSomethingElse:result]; // no problemo
[result release]; // caller has full control
}
vs. the shared case
- doSomething
{
NSString *result;
result = [ofProcessObject processedString];
[ofProcessObject release];
[self doSomethingElse:result]; // oh oh, invalid
}
------------------------------------------------------
Ich selbst habe mich persvnlich stets an den
sittlichen Gepflogenheiten des Philisters beteiligt;
nicht, weil ich ihnen Wert beigemessen hdtte, sondern
weil ich - vorwdrts, immer mal wieder! - keinen Anla_
traf, mich von ihnen zu trennen. -- H. Mann
_______________________________________________
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.