Re: How to clone a mutable dictionary
Re: How to clone a mutable dictionary
- Subject: Re: How to clone a mutable dictionary
- From: Mike Abdullah <email@hidden>
- Date: Fri, 24 Apr 2009 17:34:10 +0100
On 24 Apr 2009, at 17:15, Steve Cronin wrote:
Graham;
THANK-YOU for this informative and "full-bodied" answer!
I want make sure I fully understand:
1) The "Easy Way" works only if there are no collection objects as
values in the "copied" dictionary (or other collection).
It seems to me that the "Hard Way" is ultimately necessary for
"every Cocoa programmer".
Given that, I am inclined to just implement the "Hard Way" and be
done.
It just seems too much bother to try and figure out if any random
future item is qualified for the "Easy Way". (code obfuscation- to
what end?)
Is there a compelling counter-argument against this viewpoint?
They hard way only offers a benefit over the easy way if you've got a
structure stacking 3 or more mutable objects inside each other. e.g.
the easy way on this would not copy that final mutable dictionary:
NSMutableArray
NSMutableSet
NSMutableDictionary
BUT, such an amount of stacking often suggests a poor model design.
Consider whether there should be some custom classes in there to
handle it better.
2) By establishing a category on NSObject, one goal you accomplish
is making -deepCopy available to custom objects that are sub-classed
directly from NSObject. True? Are there other reasons why one would
want to implement for NSObject? Since there is nothing to iterate
over in NSObject is this a correct implementation for NSObject:
@implementation NSDictionary (DeepCopy)
- (NSObject *) deepCopy { return [[[self class] allocWithZone:[self
zone]] init]; }
@end
Assuming you changed "NSDictionary" to "NSObject," then no. instead
you want:
return [self copy]
which will create a copy if the object supports it, or raise an
exception if it doesn't.
3) If -deepCopy is implemented as above on NSObject then when you
implement a -deepCopy on a collection it overrides the NSObject
version and all is well. Nothing special need be done (ie no need
for a separately named -deepArrayCopy).
4) The suite of collections include: array, dictionary, and set.
(I'm an NSSet fan!) The mutable flavors all inherit from these 3
base types and the countedSet inherits from mutableSet. So
implementing the -deepCopy on NSObject, NSArray, NSDictionary, and
NSSet should provide a comprehensive solution . Do you agree?
5) Your allusion to semantics is calling attention to the fact that
the returned object is to be treated in the same way as any system-
vended object from a -copy or -alloc-int. The requestor has the
responsibility for releasing the returned object.
6) The code you show for the "Hard Way" returns a mutableDictionary
where the signature promises a NSDictionary. The mutable flavor is
useful for the construction during iteration but is there a reason
for returning something other than what was promised?
The code does return what was promised: "An object that is an
NSDictionary or subclass"
It would only be a breach of contract if that dictionary were to be
somehow mutated by the category method at a later time, which is
clearly not going to happen. Returning the mutable object saves memory
usage compared to creating an immutable object. Of course this might
not be in your favour in some particularly intensive task, so you
could tweak it later if desired.
HOWEVER, there's a reason why Cocoa has both -copy and -mutableCopy.
You might find that you actually want -deepCopy AND -deepMutableCopy.
Mike.
_______________________________________________
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