Weird problem: Application terminates unexpectedly after closing NSOpenPanel sheet

  • Here is my code:

    //-------------------------------------------------------------------------------------------------
    - (IBAction)scanFolder:(id)sender
    {
    NSOpenPanel* openPanel = [NSOpenPanel openPanel];
    [openPanel setCanChooseDirectories:YES];
    [openPanel setCanChooseFiles:NO];
    [openPanel setAllowsMultipleSelection:NO];
    [openPanel beginSheetForDirectory:nil
                                    file:nil
                         modalForWindow:[sourceView window]
          modalDelegate:self
                         didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
                             contextInfo:NULL];
    }

    //-------------------------------------------------------------------------------------------------
    - (void)openPanelDidEnd:(NSOpenPanel*)panel returnCode:(int)returnCode
    contextInfo:(void*)contextInfo
    {
    if (returnCode == NSOKButton)
    {
      [self activatePath:[[panel filenames] objectAtIndex:0]];
    }
    }

    It puzzles me that the application is terminated unexpectedly without
    any error messages in the console after the stack is unwinded up from
    the openPanelDidEnd function.

    What might I be doing wrong?
  • On Jan 8, 2009, at 11:54 PM, Oleg Krupnov wrote:

    > Here is my code:
    >
    > //-------------------------------------------------------------------------------------------------
    > - (IBAction)scanFolder:(id)sender
    > {
    > NSOpenPanel* openPanel = [NSOpenPanel openPanel];
    > [openPanel setCanChooseDirectories:YES];
    > [openPanel setCanChooseFiles:NO];
    > [openPanel setAllowsMultipleSelection:NO];
    > [openPanel beginSheetForDirectory:nil
    > file:nil
    > modalForWindow:[sourceView window]
    > modalDelegate:self
    > didEndSelector:@selector
    > (openPanelDidEnd:returnCode:contextInfo:)
    > contextInfo:NULL];
    > }
    >
    > //-------------------------------------------------------------------------------------------------
    > - (void)openPanelDidEnd:(NSOpenPanel*)panel returnCode:(int)returnCode
    > contextInfo:(void*)contextInfo
    > {
    > if (returnCode == NSOKButton)
    > {
    > [self activatePath:[[panel filenames] objectAtIndex:0]];
    > }
    > }
    >
    >
    > It puzzles me that the application is terminated unexpectedly without
    > any error messages in the console after the stack is unwinded up from
    > the openPanelDidEnd function.
    >
    > What might I be doing wrong?
    > _______________________________________________

    It's hard to say. Use the debugger and add a breakpoint on
    objc_exception_throw. Then, look at the bt when the crash occurs (on
    Leopard).

    corbin
  • I have found that the cause of the problem was that my XIB main window
    was of class NSPanel, not NSWindow.

    When the main window is an NSPanel, the application indeed attempts to
    quit and calls its NSApp delegate
    -applicationShouldTerminateAfterLastWindowClosed: message when the
    sheet gets closed. If the delegate returns NO or does not exist, the
    application does not quit (it was YES in my case). It seems that when
    the sheet gets closed, the application somehow decides that it's been
    the last window, and attempts to quit.

    I have noticed the same behavior when I simply double-click on the
    title of the main window, without any sheets, and it gets minimized to
    the Dock. Also in this case the
    -applicationShouldTerminateAfterLastWindowClosed: is called and if
    returned YES, the application quits.

    The "Release on close" option of the main window in the XIB does not
    affect anything in this regard.

    I guess it's an undocumented bugofeature of Cocoa :)

    Thanks!

    On Fri, Jan 9, 2009 at 6:18 PM, Corbin Dunn <corbind...> wrote:
    > On Jan 8, 2009, at 11:54 PM, Oleg Krupnov wrote:
    >
    >> Here is my code:
    >>
    >>
    >> //-------------------------------------------------------------------------------------------------
    >> - (IBAction)scanFolder:(id)sender
    >> {
    >> NSOpenPanel* openPanel = [NSOpenPanel openPanel];
    >> [openPanel setCanChooseDirectories:YES];
    >> [openPanel setCanChooseFiles:NO];
    >> [openPanel setAllowsMultipleSelection:NO];
    >> [openPanel beginSheetForDirectory:nil
    >> file:nil
    >> modalForWindow:[sourceView
    >> window]
    >> modalDelegate:self
    >>
    >> didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
    >> contextInfo:NULL];
    >> }
    >>
    >>
    >> //-------------------------------------------------------------------------------------------------
    >> - (void)openPanelDidEnd:(NSOpenPanel*)panel returnCode:(int)returnCode
    >> contextInfo:(void*)contextInfo
    >> {
    >> if (returnCode == NSOKButton)
    >> {
    >> [self activatePath:[[panel filenames] objectAtIndex:0]];
    >> }
    >> }
    >>
    >>
    >> It puzzles me that the application is terminated unexpectedly without
    >> any error messages in the console after the stack is unwinded up from
    >> the openPanelDidEnd function.
    >>
    >> What might I be doing wrong?
    >> _______________________________________________
    >
    > It's hard to say. Use the debugger and add a breakpoint on
    > objc_exception_throw. Then, look at the bt when the crash occurs (on
    > Leopard).
    >
    > corbin
    >
    >
    >