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: Keith Blount <email@hidden>
- Date: Fri, 5 Feb 2010 13:04:06 -0800 (PST)
Hi,
Graham - I think your solution fixed it, thanks! I finally caught a situation in which it always crashed: when a document window gets closed in my app, it automatically saves any unsaved data. This can take a second or two for large projects, but if as it was saving I immediately went to the File menu and opened another project, my array controller didn't get released immediately. Normally, the sequence would be this:
1) Click to close document window.
2) Main window controller deallocates.
3) Array controller owned by the main window controller deallocates.
However, if after clicking on close I immediately go to the File menu to open another project as the first one is still closing, the sequence is this:
1) Click to close the document window.
2) Main window controller deallocates.
3) New project opens from file menu and all its data is loaded up.
4) Array controller from old project deallocates only after the other project has finished loading.
Presumably the array controller is being autoreleased after being disconnected in its nib somewhere internally, but it *is* getting released after all. The problem is that during 3), the project that is loading sends out some notifications while the array controller is still around, so the array controller still in memory picks them up and checks to see if they are coming from its main document or window controller, but these no longer exist so it panics and quits.
Following your suggestion and just ensuring that the array controller has its reference to the main window controller/document set to nil as they deallocate fixes everything. (I've also followed your suggestion and now remove it as an observer at that point too.) Now, it no longer receives those notifications, and even if it did its pointers to the main document and window controller are nil anyway, so the crash doesn't happen and the array controller can release as it should soon afterwards.
So, thank you very much for the help, much appreciated!
All the best,
Keith
--- On Fri, 2/5/10, Graham Cox <email@hidden> wrote:
> From: Graham Cox <email@hidden>
> Subject: Re: Debugging (apparently) random retain loop bug (NSArrayController)
> To: "Keith Blount" <email@hidden>
> Cc: email@hidden
> Date: Friday, February 5, 2010, 1:11 AM
>
> On 05/02/2010, at 11:41 AM, Keith Blount wrote:
>
> > Many thanks for the reply, much appreciated. The
> strange thing with this one is that I've been through the
> code in all the obvious places and I can't find that it's
> been retained anywhere. It's an NSArrayController subclass
> that is only really used in one place in the application,
> and any other object that accesses it does so through the
> main window controller. It's not added as a represented
> object anywhere. The only thing I can think is that it as it
> is instantiated in Interface Builder, it is being retained
> through its bindings somewhere in certain circumstances.
> After posting I thought I had narrowed in on it a little bit
> - I found a circumstance in which it seemed to crash every
> time. But then it stopped crashing again even though I'm
> doing exactly the same thing... Very strange.
>
> As I've not used NSArrayController nor bindings I can't
> help much with what the likely cause is, beyond it being an
> extra retain, which you've already understood. Unfortunately
> it is a bugger to track down 'who is retaining me' and as
> far as I know there isn't much to help out with that.
>
> > I'm curious that you say that the "true cause" is the
> stale pointer to the document. I could fix this part easily,
> but have avoided doing so because it was my understanding
> that although the stale pointer was indeed the cause of the
> crash, the true bug was this object not getting released
> properly. So I was leaving it to crash in this situation in
> the hope of finding the underlying problem (fortunately this
> is in a beta version of the next version of the product
> rather than in the official release version).
>
> Well, I call it the 'true cause' because it's a question of
> clear lines of ownership. The document is the One True
> Owner™ of (some object), so it is responsible for making
> sure that any weak references that object holds to itself
> are removed when the document is dealloc'ed. The reference
> must necessarily be weak to avoid a retain cycle, but as its
> owner, the document is clearly responsible for ensuring that
> weak reference is removed. This is exactly the same as for
> other similar weak references such as delegates, etc. Also,
> as its owner, the document shouldn't really care who else
> might have a (perfectly legitimate) retain on that second
> object - it owns it, so is free to nil out the back
> reference. Anyone else retaining it is not the One True
> Owner so must be willing to accept that the real owner can
> change its state without notice.
>
> I guess your concern is that this additional retain might
> be a leak. If so, maybe Instruments can help with that. My
> view would be that a leak is a lot less serious than a
> crash, so even if the object is leaking it would be better
> to defuse it as far as possible so that it doesn't cause an
> explosion. Maybe you could call this the principle of 'don't
> leave unexploded bombs lying around'. Perhaps you could also
> use the setting of 'owner' to nil to also remove itself as a
> notification observer (rather than waiting until dealloc to
> do that), so it stops responding to notifications as well,
> to be doubly safe. (And to assist with tracking the retain
> culprit down, you could try using the owner being nil to
> trigger some sort of conditional logging or breakpoint when
> the object is messaged after it should have gone - for
> example a breakpoint on release with a condition of owner ==
> nil ought to find it assuming that it's not leaking).
>
> --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