On Mar 8, 2012, at 8:39 AM, [email protected] 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 protected])

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to