views:

375

answers:

3

Is there any reason to go with either of these, other than one returning an autoreleased object and the other needing a manual release?

NSMutableDictionary *drink = [[NSMutableDictionary alloc] init];
// do things ...
[drink release];

OR

NSMutableDictionary *drink = [NSMutableDictionary dictionaryWithCapacity:10];

gary

+4  A: 

These are convenience methods that are useful for reducing the amount of code you have to write, and are there to help in certain circumstances.

The object you get will have no real differences other than that the +dictionaryWithCapacity: and +dictionary methods will be autoreleased, and the one returned by -init won't.

As an aside, if you know how many items will be put into the dictionary, +dictionaryWithCapacity: and -initWithCapacity: will provide a slight boost in efficiency since the dictionary will be able to allocate the right amount of memory right off the bat.

iKenndac
If you look at the docs for CFMutableArrayRef (which is toll-free bridged with CFMutableArray) you'll see that initializing with a given capacity is a case where you can get handed back an instance other than the one you passed to the init method. This is understandable, since large-capacity arrays use a different private subclass that handles lots of values much better. Basically, you provide a hint of how many values you intend to store in the array. You can exceed that and it will adapt, so getting in the ballpark will help prevent wasted space.
Quinn Taylor
CoreFoundation mutable collections created with a non-zero capacity were fixed at that capacity from Mac OS X 10.0 through 10.4. Leopard eliminated the fixed-mutable collection types in favor of the variable-size collection types formerly used only when a capacity of 0 was specified. Apple's "Collections Programming Topics for CoreFoundation" has not been updated to reflect this; you'll only find this tidbit in 10.5's CoreFoundation framework release notes.
Jeremy W. Sherman
+1  A: 

The first one will init a NSMutableArray with the default size. So internally the NSMutableArray will realloc space as needed when you're adding new key:value to it. Indeed, you have to release it yourself, no autorelease is called by init.

The second one will pre-alloc 10 slot in your object. It's better in this regards if you know in advance how many items you'll have in your dictionary. This method will be autoreleased. You can also call initWithCapacity that won't be autoreleased like init but with a preallocated size.

As a convention all methods beginning with init must be allocated with alloc and release by your code explicitly and static method like dictionary* are autoreleased.

Vincent
A: 

the only reason I can think of to choose one method over the other is for performance reason... and only in an extreme case.

example case, adding a million objects to NSMutableArray

with [[NSMutableArray alloc] init], it'll have to realloc a million times, each time an object is added.

with [[NSMutableArray alloc] initWithCapacity:1000000], the array will be allocated with enough memory for a million objects at the get-go, so you don't incur the added overhead that the first method has.

so if you know how many items you want to put into the array beforehand, go for an initial capacity.

if you don't, then go for the default alloc+init.

here's a nice article that may give more insight: http://cocoawithlove.com/2008/08/nsarray-or-nsset-nsdictionary-or.html

pxl
“… it'll have to realloc a million times …” Not necessarily. If they're smart (and they generally are), it'll allocate space for some number of extra objects each time, specifically so that it doesn't have to realloc one million times. I do agree with your conclusion, though: If you know that the array will hold X times Y objects, let NSArray know that number.
Peter Hosey