When should an NSDocument stop being an NSWindow's delegate?

View: New views
4 Messages — Rating Filter:   Alert me  

When should an NSDocument stop being an NSWindow's delegate?

by David Chisnall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I am currently experiencing some crashing due to an NSWindow's  
_performClose method being called after the document (which was its  
delegate) is freed.  It looks like there is something wrong in the  
NSDocument infrastructure, because the _window ivar is never retained  
by NSDocument, but it is released on -dealloc (possibly this should be  
a -performClose or similar, because NSWindow is meant to retain itself  
and release itself when it is closed?).

This usually doesn't make much difference, because the window  
controller takes ownership, and then sets the _window ivar in the  
document to nil, and so the release message is sent to nil instead of  
the window.

The problem comes if you follow the common pattern of setting the  
document (the file's owner) as the window's delegate in the nib.  In  
order for this not to crash when the window sends a  
respondsToSelector: message to the delegate while closing, the  
document must remove itself as the delegate before it exists.  This  
would be easy, except that the window controller has stolen the window  
and the window controller itself has removed itself from the array of  
window controllers by the time -dealloc is called, so there is no way  
for an NSDocument subclass to get the window in -dealloc and do this  
removal...

David

-- Sent from my Apple II



_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@...
http://lists.gnu.org/mailman/listinfo/gnustep-dev

Re: When should an NSDocument stop being an NSWindow's delegate?

by Fred Kiefer :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David Chisnall schrieb:

> I am currently experiencing some crashing due to an NSWindow's
> _performClose method being called after the document (which was its
> delegate) is freed.  It looks like there is something wrong in the
> NSDocument infrastructure, because the _window ivar is never retained by
> NSDocument, but it is released on -dealloc (possibly this should be a
> -performClose or similar, because NSWindow is meant to retain itself and
> release itself when it is closed?).
>
> This usually doesn't make much difference, because the window controller
> takes ownership, and then sets the _window ivar in the document to nil,
> and so the release message is sent to nil instead of the window.

What goes on here is really some unusual coding and it took me some time
to accept it. If you have a better way of doing this ownership transfer
that is required in the common case. I am willing to change this.
But what ever goes on here is totally unrelated to the issue you are
having. Just forget about this _window ivar.

> The problem comes if you follow the common pattern of setting the
> document (the file's owner) as the window's delegate in the nib.  In
> order for this not to crash when the window sends a respondsToSelector:
> message to the delegate while closing, the document must remove itself
> as the delegate before it exists.  This would be easy, except that the
> window controller has stolen the window and the window controller itself
> has removed itself from the array of window controllers by the time
> -dealloc is called, so there is no way for an NSDocument subclass to get
> the window in -dealloc and do this removal...

Your problem is that you have the document as the delegate of the
window, but don't have a way to remove this relationship, when the
document gets deallocated. I think the best you can do in that case is
to remove the delegate of the window in _removeWindowController:. But at
that time the controller no longer has a reference for that window. We
may need to swap a few lines of code here.
The GNUstep code of NSWindowController has special handling for the case
where the controller is the delegate of the window. Perhaps this
constellation would fit your needs better? Or we could add similar
special code for the document being the delegate at the same place?


_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@...
http://lists.gnu.org/mailman/listinfo/gnustep-dev

Re: When should an NSDocument stop being an NSWindow's delegate?

by David Chisnall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 25 Oct 2009, at 20:36, Fred Kiefer wrote:

> What goes on here is really some unusual coding and it took me some  
> time
> to accept it. If you have a better way of doing this ownership  
> transfer
> that is required in the common case. I am willing to change this.
> But what ever goes on here is totally unrelated to the issue you are
> having. Just forget about this _window ivar.


If I had a better way, then I'd have committed it already.  I am not  
fully convinced by the transfer of ownership, nor why it is required  
that the _window ivar goes away.  Given that this is set in the nib  
file, it seems wrong that you should be able to set the window in Gorm  
and then a call to -window will not return the Window immediately  
after the nib is loaded (as happens now).  I haven't tested whether  
this is what happens on OS X, but I'd be very surprised if it is.

Presumably the question of ownership arises for the purpose of  
removing retain cycles.  I'd expect, therefore, that the solution  
would be to use one of the spare flags in the class to indicate  
whether it owned the window, and to remove it if it did.  
Unfortunately, this doesn't seem to work (or, didn't when I tried it;  
possibly I missed something).

I'm not entirely sure what the best approach is, but I'll keep thinking.

> Your problem is that you have the document as the delegate of the
> window, but don't have a way to remove this relationship, when the
> document gets deallocated. I think the best you can do in that case is
> to remove the delegate of the window in _removeWindowController:.  
> But at
> that time the controller no longer has a reference for that window. We
> may need to swap a few lines of code here.

That was my third thought, but for as you say, the controller is no  
longer the delegate here.

> The GNUstep code of NSWindowController has special handling for the  
> case
> where the controller is the delegate of the window. Perhaps this
> constellation would fit your needs better? Or we could add similar
> special code for the document being the delegate at the same place?

That might be possible.  That was my second thought, but I avoided it  
because now you have one class controlling the relationship between  
two other classes, which seems a bit fragile.

David

-- Sent from my IBM 1620



_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@...
http://lists.gnu.org/mailman/listinfo/gnustep-dev

Re: When should an NSDocument stop being an NSWindow's delegate?

by David Chisnall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 25 Oct 2009, at 22:19, David Chisnall wrote:

> Presumably the question of ownership arises for the purpose of  
> removing retain cycles.  I'd expect, therefore, that the solution  
> would be to use one of the spare flags in the class to indicate  
> whether it owned the window, and to remove it if it did.  
> Unfortunately, this doesn't seem to work (or, didn't when I tried  
> it; possibly I missed something).


I did miss something.  The window that was set as the delegate is not  
causing problems, but some other window is.  This appears to be the  
window containing the app's menu.  I'm not sure why this would have  
inherited the delegate from the other window though.  It seems to be  
related to some recent changes in handling the closure of the last  
window in document-driven apps.

David

-- Sent from my Cray X1



_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@...
http://lists.gnu.org/mailman/listinfo/gnustep-dev