Re: In-loop releasing of objects does not free memory?
Re: In-loop releasing of objects does not free memory?
- Subject: Re: In-loop releasing of objects does not free memory?
- From: Jim Correia <email@hidden>
- Date: Thu, 14 Feb 2008 22:57:48 -0500
On Feb 14, 2008, at 4:22 PM, Keith Duncan wrote:
I've filed a bug on this and would encourage everyone to do the same.
In my opinion -drain should do as the name implies; call -release on
all the objects currently autorelease'd but not release the pool
itself.
There's a limit to how much information can be inferred from the
method name. Cocoa's generally good naming conventions cannot replace
the API documentation.
Consider why -drain exists, and why it is somewhat of a special case.
In the usual case, alloc/copy/retain is balanced by release/
autorelease. (Please see the API doc for a complete discussion of the
object ownership and memory management policy.)
The documentation for -drain says that in a non-GC app -drain, when
sent to an NSAutoreleasePool, behaves identically to -release.
Ugh. Special case. I hate special cases. I file bugs about special
cases. So why do we have this special case?
NSAutoreleasePool is already somewhat of a special case. You can't
send -autorelease to an autorelease pool. (Can't in the sense that it
will raise an exception. But it doesn't make sense anyway; if you were
willing to autorelease the pool you didn't need the inner pool to
begin with.)
So why is there a -drain, that behaves identically to -release in a
non-GC application?
To answer that, we need to consider if autorelease pools are at all
useful in GC code. Any place where you'd previously managed the high
water mark of memory allocation using an NSAutoreleasePool, you could
achieve the same effect by sending the collector a -collectIfNeeded
message. But that would mean a) rewriting existing code and b) the new
code would only work in GC mode.
Yes, I realize that Apple only recommends GC for new development, and
that porting memory managed code to GC often will require additional
work beyond flipping the switch and recompiling.
The second point is perhaps more salient - reworking the code to
message the collector directly will only work in GC mode. Again,
writing dual mode code is not typically recommended, but there are
situations where it is necessary. (One of those situations is
framework development at Apple itself.)
So, leaving the inner autorelease pools around seems like a win. In GC
mode they can message the collector, in non-GC mode they can do what
they always did.
But that creates a problem. The previous idiom was
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
...
[pool release];
But -release is a no-op in GC code. NSAutoreleasePool will never get
the message. So we need a new message that we can send
NSAutoreleasePool that it will actually get when running in GC mode.
And for convenience, in non-GC mode it should do the same thing as -
release always did, to provide a single, simple idiom for inner
autorelease pools that will work in either GC or non-GC mode.
Yes, strictly speaking, it is inconsistent. But also necessary; the
alternatives would be uglier.
[This is a fictional story. I wasn't privy to the design discussion
for the -drain message. I'm just piecing together a reasonable
explanation for why the way things are the way they are.]
- Jim
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden