Re: Convenience Methods
Re: Convenience Methods
- Subject: Re: Convenience Methods
- From: Wade Tregaskis <email@hidden>
- Date: Wed, 26 Sep 2007 22:59:40 -0700
The "trick" is that when coding your own algorithms that depend on
immutability, you absolutely must copy whatever immutable object
you are using. If the object was truly immutable, the copy is very
cheap and just retains and returns the same object again. If the
object wasn't truly immutable, the copy may be expensive, but it's
necessary and will produce the needed immutable object.
You must be able to use an NSMutableArray in any situation where an
NSArray can be used because NSMutableArray is a subclass on
NSArray. However, because of this, no algorithm can safely assume
that the NSArray it was just given is really immutable.
When you retrieve an array and then use it immediately, in the same
method, you can often be pretty sure no other code is running that
modifies that array*, so you know that regardless of the
implementation it is not going to change (if you don't mutate it
yourself, of course). If you hang onto it past the end of your
method, then you should be at least retaining it, or if you know you
want it to remain unchanged, copying it. And if you do something
like call a getter for property X, then the setter for the same
property, you should as someone with even a little ObjC experience
guess that it probably will release the old value, so you should
retain it beforehand if you want to ensure it stays valid.
Now, it's true that because many objects just return their mutable
ivars directly, you can hit problems with this. For example, I've
seen it crop up occasionally that people will ask for, say, a window
title, and then do something which modifies it, and then, oh my, they
just messaged a freed object or it changed or whatever. This is why
some people believe the correct approach for a getter is to retain/
autorelease or copy/autorelease as appropriate. I've seen arguments
on this rage like you wouldn't believe, and I don't think there's an
ideal solution... my opinion is that it's not worth the performance
hit for a rare and [typically] easily diagnoses and resolved
problem. You're free to do things your own way, but like it or not
there's plenty of people who share my approach, so you'll have to
deal with it anyway.
In terms of the perversion of returned types by the caller -
'knowing' they're really mutable and mutating them - well.... that
objects may return mutable instances where their API says they're
immutable, that's typically a performance optimisation (often
premature) and an internal detail, but if you're using strong types
you'll probably be okay, because e.g. you'll be told that NSArray
doesn't respond to addObject:. Easy. And if you go and cast it to a
mutable array, well, you've broken your contract with that API,
you've assumed an implementation detail, you've gone against the
spirit of the API, so, it's hard to feel sorry for you. It's your
foot to shoot if you're so inclined.
(granted it's possible you'll pass that array along N times, and then
some object will innocently ask if it's mutable or not, and then go
poke it... yes, it's true, it's a flaw in this system, but it's
uncommon enough that you can just deal with it if it crops up...
ignorance is bliss :D )
Wade
* = It doesn't matter if your app is multithreaded; if it is and
you're sharing data between threads, you should be using
synchronisation mechanisms at appropriate places to ensure this is
true anyway. Multithreading is a separate issue.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden