Re: Debugging (apparently) random retain loop bug (NSArrayController)
Re: Debugging (apparently) random retain loop bug (NSArrayController)
- Subject: Re: Debugging (apparently) random retain loop bug (NSArrayController)
- From: Graham Cox <email@hidden>
- Date: Fri, 5 Feb 2010 10:10:23 +1100
On 05/02/2010, at 7:21 AM, Keith Blount wrote:
> Occasionally, if you close a document (NSDocument subclass) in my app and then open another document (or reopen the same document), the app crashes. I've debugged this to the extent that I now know the cause, at least. What is happening is that sometimes when a document gets closed, a particular NSArrayController subclass instance isn't getting deallocated - but only sometimes. Then, when another document gets loaded, one of the notifications it sends out is picked up by the array controller still in memory which was registered as an observer for that particular notification; the array controller then tries to call out to other parts of its associated document - but of course they no longer exist, and neither should it, so it crashes.
[]
> Has anybody got any good advice (or links to good advice) on how to track down something like this? At the moment I'm stumped because I can't seem to make it reproduceable every time.
I tracked down a crash in my app the other day which is an exact clone of this - an object owned by the document wasn't getting deallocated, then a later notification was picked up by it, and referred to the now non-existent document.
The cause is likely simple - something else is retaining the owned object besides the document, and that retain is still in force at the time the document is dealloc'ed. The problem is to find who the hell is doing that - for me that took a lot of detective work over several hours. The culprit in my case turned out to be a menu in the main menu bar holding the object as a -representedObject in one of its menu items, but there's no reason why it would be exactly that in your case. I tried overriding -retain so I could log who was calling it but unfortunately that wasn't helpful, as all sorts of things were retaining the object briefly so it just led to a lot of noise. In the end it was a case of narrowing down the circumstances that triggered the extra retain and working through the code line by line - I got lucky in that I realised it was access to any menu that led to the bug.
I also fixed the true cause of the bug - the object having a stale pointer to the document. So in my document's -dealloc method, I simply null out the secondary object's reference to self (e.g. [secObject setOwner:nil];). That should work for you as well. Then, even if something else is retaining the secondary object, it isn't holding a stale reference to the document, so while it will respond to the notification as usual, it will message nil safely instead of the stale document. In general you should null out any weak "back pointers" like this when the true owner of an object is dealloc'ed - in this case I'd overlooked this one, which was the real bug, but the additional retain made it show up.
hth,
--Graham
_______________________________________________
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