> be made to behave correctly anyway. For example, you'd never do a
> thing like this:
>
> {
> NSData *data = [[NSData alloc] initWithBytes:foo length:bar];
> const char *bytes = [data bytes];
> [data release];
> CrashByDoingSomethingWithBytes(bytes);
> }
>
> Why should this sort of thing be expected to work, just because the
> property in question happens to be an object?
Correct, I'd never do that. I know accessing NSData's internal bytes array is
definitely something that I wouldn't expect to work - that 'const char *' out
the front of -bytes tells me that I don't get to own those bytes. So I
wouldn't have done it, nor expected it to work.
Apples memory rules are explicit and short, and should never be re-stated
because you'll always get it wrong - here's Apple's webpage:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
"... if you need to store a received object as a property in an instance
variable, you must retain or copy it."
Thus, apparentl doing
NSString *s = someobject.somevar;
is essentially against the rules. You should always use
NSString *s = [[someobject.somevar {retain|copy}] autorelease];
(To my eye, not common sense, but understandable)
Quoting Peter Lewis: "if you want to keep it, retain/copy it" applies, even if
you are only going to keep it for the duration of the current method in a local
variable. This is something I wasn't completely conscious of.
If everyone adhered to that particular rule then it seems there would be no
need for the "superfluous retain/autorelease" in all accessors. However they
then go on to say:
"A received object is normally guaranteed to remain valid within the method it
was received in (exceptions include multithreaded applications and some
Distributed Objects situations, although you must also take care if you modify
the object from which you received the object). That method may also safely
return the object to its invoker"
which touches on one of my favorite sore-points that has been hashed out time
and time again in the past, that calling 'release' on an object means
"modifying" it - my example definitely released the object and knew it was
doing it. I can certainly visualise a scenario where retrieving property V
from object A might actually result in the retrieval of some hidden
implementation-specific object B's instance variables which I have no knowledge
of. I can't tell what actions I perform on A which might cause B to be
dealloc'd and thus invalidate the value of V, even if they didn't seem to
"modify" A.
However, the last sentence about the method being able to return the object to
its invoker is just bizarre - it glosses over things like 'this method has an
autorelease pool', etc. I would have thought that it makes more sense to
simply state that you should [[o retain] autorelease] anything you want to
return at all levels, rather than implicitly insisting that the bottom level
will have done it.
If you always obey the "if I stored it in a local variable, I must retain it
and thus arrange for it to be released", then the only way you could return it
to your caller would be from that local and thus it would be "legal". So, a
method may safely return the object to its invoker either:
a) directly. return [someobj foo];
b) indirectly. NSObject *val = [[[someobj foo] retain] autorelease];
return val;
Technically those are the only ways you are allowed to retrieve the value then
return it and in both cases there is zero change in 'retain count' and the
object remains alive as per Apples rules.
Jeff Laing <[email protected]>
------------------------------------------------------------------------------
A complex system designed from scratch never works and cannot be patched up to
make it work. You have to start over, beginning with a working simple system.
-- J Gall. "Systemantics: How systems work and how they fail"
_______________________________________________
Cocoa-dev mailing list ([email protected])
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]