[Openmcl-devel] NSWindow deallocation seems to work differently in CCL then it does in an XCode based application
minerva at agentsheets.com
Fri Dec 16 16:57:34 PST 2011
Ah I see the difference now, thank you Gary!
On Dec 16, 2011, at 5:21 PM, Gary Byers wrote:
> There are two significant differences between the lisp version of your code and the ObjC version:
> 1) In the lisp version, some ObjC methods are called by CCL's FFI.
> 2) In the lisp version, you create the window and view interactively
> in the listener thread; in the ObjC version, everything happens on
> the event thread.
> The first of these differences could theoretically be significant, but
> it's very hard to think of ways in which "being called by CCL's FFI"
> would affect things, aside from an outright bug in the FFI.
> It's not at all hard to imagine that the second difference causes subtly
> different memory-management behavior than would occur if the window/view
> creation and initialization happened on the main thread, and that seems
> to be the issue in your example. If you create the window and view and
> install the view on the event thread, the window will get released when it's
> Most Cocoa GUI objects expect (explicitly or otherwise) to be created
> (and, for the most part, used) on the main event thread. Some things
> work to varying degrees when done from another thread; you found a case
> where something almost works but it isn't quite right.
> CCL is involved in this to the extent that it makes it fairly easy to
> type ObjC method calls into a listener window (or evaluate forms containing
> such calls from an editor window, or LOAD them from a file ...) It's hard
> to see how it's otherwise involved.
> On Fri, 16 Dec 2011, Michael Minerva wrote:
>> I have been trying to figure out why some of our Cocoa objects do not get properly
>> decollated and I created a simple example in CCL that seems to be at the heart of
>> my problem:
>> (defclass TRASH-WINDOW (ns:ns-window)
>> ??(:metaclass ns:+ns-object
>> ? ? ?:documentation "delegate object receiving window events"))
>> (objc:defmethod (#/dealloc :void) ((Self trash-window))
>> ??(print "DEALLOC TRASH WINDOW!!")
>> (defparameter *window* (make-instance trash-window
>> ?? ? ? ? ? ? ? ? ? ? ? ? :style-mask (logior?
>> ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #$NSTitledWindowMask
>> ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#$NSClosableWindowMask
>> ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #$NSMiniaturizableWindowMask)
>> ?? ? ? ? ? ? ? ? ? ? ? ? :backing ? ? #$NSBackingStoreBuffered
>> ?? ? ? ? ? ? ? ? ? ? ? ? :defer t))
>> (defparameter *image-view* (make-instance ns:ns-image-view))
>> (#/setContentView: *window* *image-view*)
>> (#/orderFront: *window* nil)
>> If you run this little example it will create a window with an NSImageView inside
>> and show it, so far so good. ?Now when I close this window I am a little surprised
>> to see that the #/dealloc method of my trash-window never gets called. ?
>> A few other notes:?
>> ? If I do not call?(#/setContentView: *window* *image-view*) the window is
>> deallocated with no problems
>> ? If we set the content view to be a normal NSView and then close the window it is
>> released/deallocated as expected
>> ? This problem is not specific to the NSImageView being the window's content view.
>> ?If I create an NSView and an NSImageView then set the NSView to be the NSWindow's
>> content view and make the NSImagevVew a subview of the NSView then close this
>> window, dealloc is still not called.
>> So when I found all this I decided it must be some oddity of Cocoa so I decided to
>> do the same sort of thing in an XCode/Cocoa example before trying to consult the
>> Cocoa gurus, but to my surprise, my XCode example seems to behave differently:
>> // Test Code snipet
>> NSRect windowFrame = NSMakeRect(500, 500, 200, 200);
>> NSRect viewFrame = NSMakeRect(0, 0, 200, 200);
>> NSWindow* window? = [[dealloc_window alloc] initWithContentRect:windowFrame
>> styleMask:NSTitledWindowMask | NSClosableWindowMask |NSMiniaturizableWindowMask
>> NSImageView* imageView = [[NSImageView alloc] initWithFrame:viewFrame];
>> [window setContentView:imageView];
>> [window orderFront:nil];
>> // snipet from the class "dealloc_window"
>> - (void) dealloc
>> ? ? printf("DEALLOC");
>> ? ? [super dealloc];
>> When I ran this example which programmatically creates an NSWindow with an
>> NSImageView as its content view and then close the NSWidnow, strangely dealloc IS
>> called. ?It seems to be that these two examples are basically the same but seem to
>> exhibit very different behavior. ?Anyone have any clues about what could be going
>> on here?
More information about the Openmcl-devel