Re: How do I debug weak_unregister_no_lock?
Re: How do I debug weak_unregister_no_lock?
- Subject: Re: How do I debug weak_unregister_no_lock?
- From: Quincey Morris <email@hidden>
- Date: Wed, 15 Jan 2014 00:59:05 -0800
On Jan 15, 2014, at 00:23 , Ken Thomases <email@hidden> wrote:
> That doesn't make sense. A weak reference can't be the only reference to an object. As I'm sure you know, objects are deallocated (and weak references nil'd) when the last *strong* reference is broken.
I think this was the scenario:
— I had an object A with a __weak reference to an object B.
— Object B had previously been CFRetain’ed via a __bridge. (Yes, I know this is awful, but I was converting code that was designed for GC and I couldn’t find an elegant way of converting it to ARC without creating irresolvable reference cycles, yet convert it to ARC I must. So: manual retains.)
— Another object, C was responsible for CFRelease’ing B, and it did this in object C’s dealloc. Object C was actually in the undo history of the document, which is why it needed to keep B alive longer than everything else did.
— C did not have a direct reference to B, but found the reference via a chain of references that went through object A.
— When C’s reference count went to zero, object A’s reference count had also gone to zero and A’s dealloc was still pending. (This is the part I’m a bit hazy on, but the zeroing of weak references seems to be deferred sometimes, perhaps to avoid recursion in a dealloc that is invoked because a weak reference is already being zeroed.) Thus, the chain of references through A still existed — and in a sense A still existed because its dealloc hadn’t run yet.
— C tried to CFRelease B, and it crashed because it couldn’t find B via its indirect reference to A.
When I found the place this was happening, I could see all this in the debugger. Specifically, I could see a __weak ivar with a non-nil value, but the object wasn’t message-able. I think the debugger reported it as nil in ‘po’, but it clearly wasn’t.
Incidentally, my fix was to make A’s reference to B __unsafe_unretained, which had the same functionality as the __weak reference but didn’t get tangled up in the zeroing. Another awful solution, but it was the best I could come up with.
_______________________________________________
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