Re: ivar access during -finalize
Re: ivar access during -finalize
- Subject: Re: ivar access during -finalize
- From: Nick Zitzmann <email@hidden>
- Date: Thu, 08 Mar 2012 10:09:16 -0700
On Mar 8, 2012, at 8:39 AM, email@hidden wrote:
> I largely eschew -finalize in my GC app but on some occasions I do use it and I am seeing some resurrection problems.
> I have read "Implementing a finalize method" and "Inapplicable Patterns" in the "Garbage Collection Programming Guide".
>
> Consider:
>
> - (void)finalize
> {
> // a single reference to _myIvar is held by self
> [[NSFileManager defaultManager] removeItemAtPath:_myIvar error:NULL]
> [super finalize];
> }
>
> Which occasion leads to:
>
> Thread 9 Crashed:: Dispatch queue: Garbage Collection Work Queue
> 0 libauto.dylib 0x94712a5b void handle_resurrection<Auto::SubzoneBlockRef>(Auto::Zone*, void*, Auto::SubzoneBlockRef, unsigned long) + 683
> ...
> 5 libobjc.A.dylib 0x94644256 objc_assign_ivar_gc + 55
> 6 com.apple.Foundation 0x9102df8d -[NSFilesystemItemRemoveOperation initWithPath:] + 57
> 7 com.apple.Foundation 0x9102d547 +[NSFilesystemItemRemoveOperation filesystemItemRemoveOperationWithPath:] + 65
> 8 com.apple.Foundation 0x9102d382 -[NSFileManager removeItemAtPath:error:] + 57
> 9 com.mugginsoft.myframework 0x00291387 -[MGSBrowserImage finalize] + 183 (MGSBrowserImage.m:87)
> ...
> 16 libauto.dylib 0x94723e29 Auto::Zone::invalidate_garbage(unsigned long, void**) + 89
>
> I had initially assumed that _myIvar would be finalised after self.
> But the reality appears to be that an object and any objects referenced by ivars may be collected simultaneously.
> The crash therefore occurs when the ivar is finalised first and is subsequently re-assigned to a reference as a result of calling the NSFileManager method.
>
> Question:
> Is the above correct?
Yes.
> If so it means that finalisers need to be very carefully about manipulating ivars.
> In my case I could probably work around the issue by replacing -removeItemAtPath with unlink(2), assuming that I can get a char representation from my finalised NSString ivar.
> A more robust solution is a probably a separate -dispose method.
I'd say "definitely" instead of "probably" above. As you've discovered, it's a bad idea to do anything in -finalize that doesn't involve freeing up memory allocated outside of the garbage collector's zone, so if you must clean something up that isn't RAM, you should figure out an alternative way of doing so.
But if you really must use -finalize to clean up something that's not a manually allocated class or data structure, then at least make sure whatever you're doing is thread-safe, because -finalize is always called on a background thread. +defaultManager is not thread-safe IIRC.
Nick Zitzmann
<http://www.chronosnet.com/>
_______________________________________________
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