I have two functions which one should i use? Please explain the difference.
A:
- (NSMutableArray *)FunctionA:(int)count {
NSMutableArray *a = [[NSMutableArray alloc] init];
for (int i = 0; i < count; i++) {
[a addObject:[NSNumber numberWithInt:0] ];
}
return [a autorelease];
}
B:
-(NSMutableArray *)FunctionB:(int)count {
NSMutableArray *b = [NSMutableArray arrayWithCapacity:count];
for (int i=0;i<count; i++){
[b addObject:[NSNumber numberWithInt:0] ];
}
return b; // or [b autorelease] ?
}
The first creates a mutable array without specifying a capacity. This causes the array to have to grow when you add items. Internally, this is probably heavily optimized to occur "chunks at a time" but it's still necessary to grow the array and allocate more space when adding items.
The second gives the array a hint (you're probably going to need "this much" room) to avoid the overhead of growing the array when adding a known number of objects. Of course it will still grow larger if needed (as if you hadn't specified a capacity). You should use this approach if you already know the count ahead of time. It's faster with a large count.
This has a downside if you haven't measured before optimizing, however: If you're creating a mutable array with a very high capacity but not always using that capacity, you incur the penalty of allocating all that space for nothing.
Also, you don't autorelease B (as you commented out) because you didn't create the mutable array with init - you used a convenience method which did it itself, which means you're not responsible for releasing it. As I mentioned in a comment to another answer to your question, you can also create the array with:
[[NSMutableArray alloc] initWithCapacity:capacity];
... then release it when ready. This gives you greater control over memory usage than using the autorelease pool, which is an important consideration on the iPhone platform.
Remember, though: measure first, then optimize if necessary.
Mutable objects still need to allocate space so that will allocate a default amount for say 10 objects. If you add an 11th, the mutable array will have to allocate new memory, copy the items over to the new memory, and free the old memory.
This is normally so fast you won't even notice but it could slow it down. Creating the mutable array with a size creates the array of the specified size initially so hopefully less resizing will occur.
In the first example, you must manage the memory of the array, since you create it using +alloc
and -init
(which is why you need to send -autorelease
to it).
In the second example, you do not have to manage the memory of the array, since it is returned to you autoreleased (because you created it using a convenience method). Also since you specify the desired size of the array up front, it is likely to be more efficient.
If you want to return an autoreleased array, then the second option would probably be more preferable, since +arrayWithCapacity:
will return an already autoreleased array. Also since the array returned to you is already autoreleased, you do not have to send -autorelease
to it yourself.
If you have any more concerns with memory management, then reading the Apple Memory Management Guidelines is a must.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With