简体   繁体   中英

NSPanel causes subsequent use of NSOpenPanel to generate an exception

I have an app that uses a NSOpenPanel so that the user can select multiple files for import and also has a typical preferences panel. The prefs panel is stored in the .xib file.

A problem occurs after the user has called up the preferences panel. Until then the NSOpenPanel works absolutely fine, all logic is executed in the completion block and it can be re-called again and again. However, once the user sellects the Preferences option and dismisses that sheet then every subsequent call to -(IBAction)addFiles: causes an exception:

They're declared like this:

@interface BQSAppDelegate
{
    NSOpenPanel *addFilesPanel;
}
@property(assign)IBOutlet NSPanel*prefs_panel; //connected to a NSPanel in the .xib

And used:

@implementation BQSAppDelegate

-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// other initialisations not to do with addFilesPanel….
    addFilesPanel = [NSOpenPanel openPanel];
    addFilesPanel.canChooseDirectories = YES;
    addFilesPanel.allowsMultipleSelection = YES;
}

-(IBAction)addFiles:(id)sender //button on main window pressed
{
    [addFilesPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
        if (addFilesPanel.URLs.count < 1 || result != NSFileHandlingPanelOKButton) {
            NSLog(@“User cancelled”);
            [addFilesPanel orderOut:self]; //I’ve tried it without this line with exactly the same results
        }
        else {
            //do things…
        }
    }];
}

-(IBAction)preferences:(id)sender //bound to the usual Apple+’,” shortcut and app menu item
{
    if (self.prefs_panel.isVisible) {
        return;
    }
    [self.window beginSheet:self.prefs_panel completionHandler:^(NSModalResponse returnCode) {
        NSLog(@"completed"); //is never executed...
    }];
}

-(IBAction)ok_prefs:(id)sender //called when the user presses a button on the Preference panel
{    
    [self.prefs_panel orderOut:self];
}

The exception is:

2015-03-18 20:35:29.913 QS[3634:241869] *** Assertion failure in void associateSheetWithHost(NSWindow *, NSWindow *)(), /SourceCache/ViewBridge/ViewBridge-103/ViewBridgeUtilities.m:83
2015-03-18 20:35:29.914 QS[3634:241869] sheet <NSVBOpenPanel: 0x1003504f0> already has a host <NSWindow: 0x6000001e5e00>
2015-03-18 20:35:29.917 QS[3634:241869] (
    0   CoreFoundation                      0x00007fff95e7366c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff8db6776e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff95e7344a +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x00007fff9399e471 -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 169
    4   ViewBridge                          0x00007fff8c931333 -[NSWindow(ViewBridgeNeedsSPI) _setSheetHost:] + 305
    5   AppKit                              0x00007fff8b367a2f -[NSVBSavePanel beginSheetModalForWindow:completionHandler:] + 69
    6   QS                          0x0000000100017684 -[BQSAppDelegate addFolders:] + 212
    7   libsystem_trace.dylib               0x00007fff8be72cd7 _os_activity_initiate + 75
    8   AppKit                              0x00007fff8acd8b71 -[NSApplication sendAction:to:from:] + 452
    9   AppKit                              0x00007fff8acd8970 -[NSControl sendAction:to:] + 86
    10  AppKit                              0x00007fff8aeae86c __26-[NSCell _sendActionFrom:]_block_invoke + 131
    11  libsystem_trace.dylib               0x00007fff8be72cd7 _os_activity_initiate + 75
    12  AppKit                              0x00007fff8ad21509 -[NSCell _sendActionFrom:] + 144
    13  libsystem_trace.dylib               0x00007fff8be72cd7 _os_activity_initiate + 75
    14  AppKit                              0x00007fff8ad3c085 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 2775
    15  AppKit                              0x00007fff8ad3b2b9 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 491
    16  AppKit                              0x00007fff8ad3a899 -[NSControl mouseDown:] + 714
    17  AppKit                              0x00007fff8b238a18 -[NSWindow _reallySendEvent:] + 12721
    18  AppKit                              0x00007fff8acbf16e -[NSWindow sendEvent:] + 446
    19  AppKit                              0x00007fff8ac71451 -[NSApplication sendEvent:] + 4183
    20  AppKit                              0x00007fff8aafd608 -[NSApplication run] + 711
    21  AppKit                              0x00007fff8aae8a14 NSApplicationMain + 1832
    22  QS                          0x0000000100001fe2 main + 34
    23  libdyld.dylib                       0x00007fff90d485c9 start + 1

It must be something to do with the way I'm calling and/or dismissing the NSPanel but I don't know what. I'd really appreciate some help.

It's a cryptic error message, and I'm not sure I understand it's wording despite the comment that solved the problem. I was thinking it had to do with there being a modal run loop associated with sheets, and it may have to do with that-- perhaps there's all the overhead of a modal session still kicking arround, alive somewhere, unless you call endSheet .

The hint was from this related question about the completion handler not being invoked. The second, unaccepted answer there does seem to indicate that you have to kill the modal session, not just kill the sheet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM