> >> Yes, and it autoreleases it too. :-o That means it'll conveniently be
> >> released later on, which is exactly what you're running into. If you
> >> want to keep a reference to the dictionary, you should call alloc and
> >> init yourself.
I wrote:
> > No, you should just *retain* the result of dictionaryWithCapacity.
mmalc wrote:
> No, you shouldn't.
With all due respect, why not? Apple gives us all those convenience methods
but you say we shouldn't use them?
(Note, my first kneejerk response was of course because I'm sure you'll find
Apple docs that say explicitly "if you want to keep a reference to <x>, you
should retain it" whereas it's unlikely you'll find anything that says "if you
want to keep a reference to <x>, you're probably using the wrong design
pattern")
(Oh, and, dictionaryWithCapacity: is really not one I'd get in a fuss about.
But some of the other dictionaryWithObjects: convenience methods are too damned
handy to lose. I just don't think that "best practice" should be something
that changes depending on which particular convenience method you are talking
about)
> If you're writing an init method and want to assign the dictionary to
> an instance variable, you should use alloc/init.
>
> If you want to assign the dictionary to an instance variable, you
> should use an accessor method. In this case, it's still better to use
> alloc/init then release the dictionary when you've finished with it.
That's seems a really aberrant case, where you are creating an empty dictionary
with a nominated capacity. I can't visualize a case where you would do such a
thing, outside of the initialiser.
> If you want to create the dictionary, use it temporarily, then forget
> about it, then dictionaryWithCapacity is OK, but again (particularly on
> iPhone) best practice is still to use alloc/init+release.
There are cases like the NSFileManager where you need to pass in a dictionary
of options that describe the directory being created (for example) - should I
really be creating temporary variables for those, or using the convenience
methods (dictionaryWithObject:forKey:)?
I'm assuming you are saying 'don't use the convenience methods because the
autorelease pool won't empty quickly enough'. Certainly Ken said it, though he
seemed to assume that there was only one pool, that people would not be
creating their own in their known trouble-spots.
Ken Thomases wrote:
> The autorelease pool is convenient and in some cases necessary, but it
> does come at some cost. It has some overhead in terms of time and
> memory, plus it tends to increase the peak memory usage of your
> program. (Over time, assuming you've got all your memory management
> correct, a program's memory usage will come out the same, but
> autoreleased objects accumulate over the lifetime of the current pool,
> causing spiky memory usage.)
But implicit in that seems to be that -[NSDictionary initWithObjectsAndKeys:]
won't add to the auto-release pool and I don't see where that's a valid
assumption (or at least a documented assumption). If you look at some of the
stack traces in Instruments, you find things being created way down in the
bowels of the frameworks that you wouldn't necessarily expect. (Date
Formatter, I'm looking at you)
I'm increasingly of the opinion that to be properly paranoid (that is, to not
assume anything about the behavior of 3rd party (including Apple) classes) and
survive in the limited memory world of the iPhone, you should be writing your
initialisers like this:
- (id)initLikeJeffThinksYouShould
{
if (self = [super init]) {
// Assume incompetence in others and you'll never be disappointed, only
pleasantly surprised.
NSAutoreleasePool *pool = [NSAutorelease pool new];
_var = [[SomeoneElsesClass someMethodWhichMightFillThePool] retain];
[pool drain];
}
return(self);
}
That's all putting aside that by calling dictionaryWithCapacity: it seems to me
that the NSMutableDictionary framework has more chance of re-using one it had
lying around in some cache - yes, initWithCapacity: could do that as well, but
there would still be the memory-churn expense of the alloc/release that would
not be needed by dictionaryWithCapacity
It might not do it today but if I give the system the clearest possible
indication of what I want (and not just the steps I think it should go
through), I leave more scope for clever software engineers to add extra
optimizations under the covers in future revisions.
_______________________________________________
Cocoa-dev mailing list ([email protected])
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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]