On 29 Jun 2011, at 5:43 PM, James Merkel wrote:
> In the [Memory Management Programming Guide] it says:
> 
> "You should typically not manage scarce resources such as file descriptors, 
> network connections, and buffers or caches in a dealloc method. In 
> particular, you should not design classes so that dealloc will be invoked 
> when you think it will be invoked. Invocation of dealloc might be delayed or 
> sidestepped, either because of a bug or because of application tear-down.
> Instead, if you have a class whose instances manage scarce resources, you 
> should design your application such that you know when you no longer need the 
> resources and can then tell the instance to “clean up” at that point. You 
> would typically then release the instance, and dealloc would follow, but you 
> will not suffer additional problems if it does not."
> 
> In my code I close a file in the dealloc method -- so I guess that's a file 
> descriptor. I opened the file in the init method, so it seemed logical to 
> close it in the dealloc method.
> Also, not to be facetious, if I have a bug in my code, wouldn't I fix it? 
> Granted, at application tear-down, if the file is still open, it won't be 
> closed because dealloc won't be called. But again that comes under the 
> heading of a bug in the code. So I don't understand this injunction.

I don't think it should be treated as a hard rule, but I think it is good 
advice most of the time, or at least a good starting position.

One way to look at it is that for most objects you're not supposed to assume 
very much about their lifetime. You know they exist as long as you have a 
refcount to them, but they *may* continue to exist after you release them. This 
is the semantic of -release. You may happen to know, in a particular piece of 
code, that you have the only reference to something and it will be dealloced 
with a given release. But thinking of release as equivalent to dealloc will get 
you into trouble.

Even ignoring GC (which makes dealloc/finalize even more uncertain), you might 
end up stashing a reference to that object somewhere else, extending its 
lifetime. Maybe it's in an NSNotification or an undo stack or a debug log, or 
there's a situation where your autorelease pool lasts longer than you expect 
(perhaps you are dealing with a bunch of files in a loop as you load or save a 
document, eg). In my experience it isn't *usually* a problem of leaking the 
file handles entirely; it's a problem if I temporarily accumulate too many of 
them, or if I need the file handle (or socket or...) to be closed before I do 
some operation, and simply calling -release isn't normally a guarantee of that.

My preferred approach is to have a -close or -invalidate method that releases 
resources, breaks retain cycles, etc.. If -invalidate isn't called before 
dealloc, that's OK, but I can also call -invalidate explicitly if I know I want 
to tear down the object at a given time.

I think there are cases where the indefinite lifetime *is* what you want, if 
you have objects that can lazily fault something in from disk, or which 
encapsulate a sharable server connection, or etc. But those objects should be 
the exception, so that you can be especially aware of lifecycle issues in any 
code that deals with them. And even so, I usually end up having to give them an 
-invalidate method eventually, to deal with some odd situation.


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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 arch...@mail-archive.com

Reply via email to