Re: Caution regarding NSDirectoryEnumerator
Re: Caution regarding NSDirectoryEnumerator
- Subject: Re: Caution regarding NSDirectoryEnumerator
- From: "Ken Thomases" <email@hidden>
- Date: Mon, 17 Jun 2002 16:53:05 -0500
- Priority: normal
On 16 Jun 2002, at 20:14, Kirk Kerekes wrote:
>
The standard sample code for NSDirectoryEnumerator is comparable to the
>
standard NSEnumerator sample code:
>
>
while(anObject = [enumerator nextObject])
>
{
>
// do stuff
>
}
>
>
Except that NSDirectoryEnumerator has two major distinctions:
>
>
1. The extent of its enumerating is often not known in advance.
>
2. It does not merely return object references, it _creates_ objects,
>
specifically NSStrings.
>
>
So if you are going to use (or perhaps abuse)
>
NSDirectoryEnumerator to plod through an entire volume to find some
>
item, (or even just let the user select a starting point for an
>
enumeration) the enumerator may be generating quite a pile of
>
NSStrings for you...
>
>
"So what", you say "they are autoreleased, and the pool will handle it".
>
>
Not so fast.
>
>
Note that even if you add a local autorelease pool to your loop code:
>
>
while(anObject = [enumerator nextObject])
>
{
>
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
>
// do stuff
>
[pool release];
>
}
>
>
-- the path strings created by the enumerator are _not_in_the_loop_pool_,
>
because the code inside the while-test is not executed "inside" the
>
while-block. Those NSStrings will continue to pile up until after the
>
entire enumeration is completed.
>
>
If you think that this is a trivial consideration, please note
>
that enumerating a single OSX boot volume can easily generate in
>
the ballpark of 100mb of NSStrings and related "hidden" allocations
>
-- at least based on my testing.
>
>
Converting the code from a pretty "while" loop to an ugly kludge
>
-- {using if(!anObject) break; -- to exit a forever-loop} that
>
puts the [enumerator nextObject] inside the autorelease pool
>
context results in a dramatic reduction in peak memory use -- in my
>
case the app went from sucking up 30% of the available memory down
>
to 0.2% -- comparable to the Console and LoginWindow processes when
>
they are _idle_.
You might find this less ugly and kludgy (or, you might find it
moreso):
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
while(anObject = [enumerator nextObject])
{
// do stuff
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
[pool release];
Keep in mind, if "// do stuff" uses the continue statement, then that
iteration won't release the autorelease pool. Probably not a problem
in most cases.
Ken
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.