Re: ivar access during -finalize
Re: ivar access during -finalize
- Subject: Re: ivar access during -finalize
- From: Quincey Morris <email@hidden>
- Date: Sat, 10 Mar 2012 19:53:18 -0800
On Mar 10, 2012, at 17:08 , email@hidden wrote:
> On 10 Mar 2012, at 22:51, Eric Wing wrote:
>
>> Just another angle on your original problem, have you considered using
>> CFRetain and CFRelease on _myIvar? These are still meaningful in
>> garbage collection mode. Using CFRetain when you get/create _myIvar,
>> it would presumably still be alive in your finalize method until you
>> call CFRelease on it.
>>
> That sounds like an inspired piece of thinking!
Hold hard, it's not that easy!
Not unless you're incredibly lucky, it isn't. If you CFRetain the ivar object, you leave yourself wide open to the problem of retain cycles, the normal lack of which is a main benefit of using GC (and the only one left, if you consider the alternative of ARC for a new project).
If you can *prove* there are no reference cycles involving the original object and the ivar object, then this approach will work fine. But how do you prove that? The frameworks introduce lots and lots of references you're not normally aware of, and reference cycles appear in surprising ways.
However, CFRetain/CFRelease would work as an implementation detail of your earlier approach, instead of inventing your own reference counting.
There are a couple of other, less vital considerations:
1. Usually, the shared resource that must be kept alive until it has no "clients" isn't the ivar object but something further downstream. Retaining the ivar object isn't fatal, but it keeps alive at least one and possibly a succession of objects that you don't really need to stay alive beyond the point of calling 'disposeResources'.
2. What you're reaching for here is a kind of 2-stage finalization. In stage 1, all the 'finalize' methods are called, and all of the objects are still "really" alive. In stage 2, all of the objects are actually disposed of. That kind of approach (if theoretically feasible, which I don't know about) would be nice, but just isn't the way Obj-C GC works.
3. As someone pointed out to me on this list a while back, it's a mistake not only to rely on garbage collection happening in a timely fashion (for example, if you need finalization to close some files in a procedure where you're creating lots of files, you can't assume the unwanted files will get closed early enough to leave enough file descriptors to open new ones) but also to rely on collection happening *at all*.
Thought experiment: If you had a computer with a *lot* of memory, you could imagine a situation where the collector never needed to run because there was always enough memory to satisfy new requests, then you might never get to reclaim your resources. If the resources are non-memory things like file descriptors, that would be bad news. Obj-C GC, though, always does run eventually, within a few seconds at most.
4. The retain/release model has an explicit guarantee about the timing of 'dispose' which you use in your code design. The GC … doesn't. Trying to pretend that it does just means lots of difficult bugs to find.
_______________________________________________
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