In article <[EMAIL PROTECTED]>, Michael Ash <[EMAIL PROTECTED]> wrote:
> In comp.lang.objective-c Sherm Pendley <[EMAIL PROTECTED]> wrote: > > Yeah, I'm a little skeptical of Apple's setters doing a -copy by default > > also. It seems to run counter to the whole idea of shared ownership that > > retain/release was designed to support in the first place. > > Ah, but the really clever bit is that if you know that your objects are > immutable, the retain/release mechanism lets you implement copy as a > simple retain. Due to this, you should always copy in setters if they take > an NSString, NSArray, etc. If it's mutable then you shouldn't be holding a > reference to the original object anyway (it could change out from under > you at any time) and if it's immutable then you get a very fast "copy" > that doesn't actually do anything. Yes. I Alan Kay's OOPSLA talk, http://video.google.com/videoplay?docid=-2950949730059754521 , he says that if you are giving out access to your parts (my string attached to a puppet's finger example) you've got a broken API. To be truly object oriented, in his view, you have an object that does things, and hides the details of HOW it does them. You tell the puppet to pick up something, and trust it to move its fingers itself. That sounds fine, until it is time for me to actually sit at a keuboard and write a program. In practice, I often have tree data structures like NSXMLDocument and NSXMLElement that I want to manipulate, and seems natural to put the manipulation vocabulary into a separate Controller object that has a legitimate need to know the details of NSXMLElement. There are at least three places I could my application's "puppet master" code: * in a separate Controller class that uses NSXMLElement * in a category of NSXMLElement * in a subclass of NSXMLElement but rather than discuss the pros and cons of each choice here, note that for any of these I'll need getters that return parts that actually modify the tree, not getters that return transient copies that, after I modify them, will be quickly discarded. So, if XCode is generating getters that return a copy, to actually modify a leaf of a tree, I'd have to get access to the leaf's owner and write: [leafOwner setLeaf:[self mymodifiedLeaf:[leafOwner leaf]]]; But it is worse than that, since my access to leafOwner would itself have come from a getter, so leafOwner is therefore a transient copy. I'd have to apply the same get, modify, set process to leafOwner's owner, and so on all the way up the tree. So, for the simplest modification of a leadnode of a tree, I have to copy the whole tree. And it is even worse than that, since if I am sharing the tree with something else, _I_ see my modified tree, but everyone else sees the original tree. That means we need getters to return actual references to our parts (some of the time) yet we want them to return copies so callers can't break our invariants. Maybe we need a naming convention: - (Foo *)foo; // returns a copy - (Foo *)refFoo; // { return foo; } // returns self->foo; In addition to the above referenced Alan Kay speech, this essay was also inspired by '"Design Patterns" Aren't' by M. J. Dominus http://perl.plover.com/yak/design/samples/slide001.html particularly http://perl.plover.com/yak/design/samples/slide012.html and following which is about getting us to think of procedures for designing maintainable software systems bigger than a single human mind can hold. _______________________________________________ Help-gnustep mailing list [email protected] http://lists.gnu.org/mailman/listinfo/help-gnustep
