Question

Which is considered the better way to derive a new dictionary from an original one:

[NSDictionary dictionaryWithDictionary:otherDictionary];

or

[otherDictionary copy];

?

From time to time we need to make a mutable dictionary out of an immutable one, and so this question keeps coming in. Maybe there is none, but I'm curious to see if in some use cases one is better than the other.

EDIT: I do know the above methods cannot be used to derive a mutable dictionary. I just wanted to ask the question in a general way, and then explain how I face this question from day to day. I should've been more clear about that.

Was it helpful?

Solution

Actually, they are different, but not for the reason you expect. I'm going to assume you're using ARC (and if you're not, why not?), so the auto-releasedness of the returned object doesn't matter.

Here's how they differ: consider what happens if otherDictionary is nil.

Well, if you use:

[otherDictionary copy]; // or -mutableCopy

You'll get back nil, because you have a nil receiver.

On the other hand, if you use:

[NS(Mutable)Dictionary dictionaryWithDictionary:otherDictionary];

You will get back an NS(Mutable)Dictionary, regardless of whether otherDictionary is nil or not.

This is nice in the situation where you need to create a copy of a dictionary and want an NSDictionary instance afterwards, but you don't want to test for nil (yay for reducing cyclomatic complexity!).

OTHER TIPS

There are a couple things about this question:

Firstly, these two are slightly different:

[NSDictionary dictionaryWithDictionary:otherDictionary];    #1
[otherDictionary copy];                                     #2

#1 returns an autoreleased object (i.e., one with a +0 retain count); #2 returns an object with a +1 retain count, so the caller is responsible for calling release at some point.

(They're also slightly different if otherDictionary is nil: #1 returns an empty dictionary, whereas #2 returns nil.)

Of course, in your question, you actually ask about mutable copies. Note you can do either of these:

[NSMutableDictionary dictionaryWithDictionary:otherDictionary];
[otherDictionary mutableCopy];

The same caveats as above apply to each of these methods.

There's probably not a best way per se, but mutableCopy is the most clear (just remember that you have to release the retained object at some point).

They're semantically equivalent. Which one to use is entirely a matter of choice. I favor -copy, just because it's shorter, and makes what's going on more clear.

If you need a mutable copy (as your text indicates), the lines you posted won't work. You need:

[NSMutableDictionary dictionaryWithDictionary:otherDictionary];

or, equivalently:

[otherDictionary mutableCopy];

In terms of memory management, -copy and -mutableCopy, return an object with a +1 retain count, meaning you need to release them when you're done with them. -dictionaryWithDictionary: returns an autoreleased object, so you don't need to release it when you're done with it, and need to retain it if you want to keep it around. In the old (pre-ARC) days, this distinction meant that which approach you used might depend on your memory management needs (they're still interchangeable after an additional retain or release, of course). Of course, if you're using ARC, this distinction doesn't matter to you.

The Cocoa-approved way is to send a mutableCopy method which returns a mutable copy:

NSMutableDictionary *mutableOtherDictionaryCopy = [otherDictionary mutableCopy]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top