Re: dealloc for cleanup versus freeing memory
Re: dealloc for cleanup versus freeing memory
- Subject: Re: dealloc for cleanup versus freeing memory
- From: John Stiles <email@hidden>
- Date: Mon, 6 Aug 2007 11:42:28 -0700
Your points are well articulated, but I still see this as defeating
the point of retain counts.
If your object is designed to hold a reference to a "scarce resource"
like a file handle, and it's being retained by three different points
in the code, it seems like a bad idea to me for one point in the code
to decide "OK, we're done now, let's wrap it up" and just close the
file. What about the other two places in the code that were using the
object? If they still hold a retain on the object, they have every
reason to expect a working file handle, right?
If you want to say that retain counts are a bad idea in general for
scarce resources, OK, but that's a much broader argument and has very
different ramifications to me.
On Aug 6, 2007, at 11:28 AM, Bill Bumgarner wrote:
On Aug 6, 2007, at 11:07 AM, John Stiles wrote:
I feel as if you remove all the benefits of reference counting if
you add a specific "cleanup" method. If some other method had
retained the object for some reason, what is it supposed to do now?
Explicit cleanup mechanisms only seem to work if you want an
object that can't be copied or shared at all, and you give up all
the benefits of refcounting for what don't appear to be very solid
benefits (basically, things "work better" even if you accidentally
leak an object).
The refcounting mechanism -- -dealloc, specifically -- is a
horrible place to clean anything up but memory.
Since I can't find it in the archives:
Begin forwarded message:
From: Bill Bumgarner <email@hidden>
Date: July 25, 2007 9:00:02 AM PDT
To: Charlton Wilbur <email@hidden>
Cc: mmalc crawford <email@hidden>, Cocoa Dev <cocoa-
email@hidden>
Subject: Re: Autorelease/Retain/Release
On Jul 24, 2007, at 8:22 PM, Charlton Wilbur wrote:
It's not hard to envision an autorelease pool optimization in a
framework where the release message is only sent if there are a
certain number of objects in the pool, though whether it would
actually provide a performance increase is doubtful; and if
there's no Cocoa event loop, such as in a shell tool, there may be
a single autorelease pool that's created at the start of the
program and released at the end; code that uses autorelease, such
as classes that may be called as part of a shell tool or as part
of a Cocoa application shouldn't make assumptions about when the
objects are released, because there's no guarantee in the contract.
This is not "quirkiness"; this is "the contract only guarantees
what the contract actually guarantees."
There is a gem here...
Namely: Do not design classes such that you are assuming that the
-dealloc will be invoked when you think it will be invoked. For
bug or valid reason, it might be delayed.
Specifically: Do not manage scarce resources in -dealloc and,
thus, manage scarce resources through reference counting. It is a
bad idea now and a fatal pattern under GC.
Design your classes such that you know when you are done with the
instances *and you tell them to be done*. At that point, the
objects can release scarce resources (file descriptors, network
connections, and buffers/caches, etc).
Under retain/release/autorelease, lumping cleanup logic into -
dealloc and, thus, piggy backing it on retain counts will lead to
some very nasty problems and bugs that are a total pain to debug.
- it naturally leads to order dependencies on object graph tear
down. In and of itself, this isn't necessarily evil. But it is
very bad to lump order dependencies into a mechanism that is
inherently non-ordered -- as soon as an object falls in an
autorelease pool, your carefully constructed, and very fragile,
order dependency just got broken.
- simple memory leaks -- very annoying, but not generally
immediately fatal -- become much more problematic as scarce
resources are not released when you expect them to be released.
"no more file descriptors" often translates to "user cannot save
data".
- similarly, leaked objects may no longer be visible on screen, but
may be still connected into the application via notifications or
other mechanisms and, thus, may impact the user experience or the
user's data in what seems to be highly mysterious ways.
- it can lead to cleanup logic being executed on the wrong thread.
If an object falls into an autorelease pool at an unexpected time,
it will be -dealloc'd on whatever thread's pool it happens to be
in. That can easily be fatal for certain kinds of resources that
really want to only ever be touched from one thread.
None of this is conjecture. These are all failure modes that I
have repeatedly run into in various bodies of code (Xcode, for
example).
Finally, there is a forward looking reasons for not lumping scarce
resource cleanup into -dealloc and, thus, overriding the memory
management specific reference counting scheme with additional
responsibilities.
Namely: Garbage Collection.
Any logic related to retain/release/autorelease and order
dependencies of -dealloc will be a complete bear to deal with under
GC. GC, by its very definition, entirely eliminates retain/
release/autorelease. As that implies, any logic tied to retain
counts will no longer work.
b.bum
(And if you are using -retainCount in production code, well... just
don't. Please. Do not do that.)
_______________________________________________
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