Re: dealloc and scarce resources
Re: dealloc and scarce resources
- Subject: Re: dealloc and scarce resources
- From: Wim Lewis <email@hidden>
- Date: Wed, 29 Jun 2011 19:17:29 -0700
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 (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