beginSheetModalForWindow - 警报窗口消失

时间:2013-04-05 10:32:29

标签: objective-c cocoa

AppDelegate中实现的这段代码出了什么问题?警报很快出现在窗口上,然后消失。永远不会调用alertDidEnd回调方法。

我试图在Xcode 4.6.1中清理产品并重建它,但没有成功。

- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
    [[alert window] orderOut:self];
    alertResult = returnCode;
    NSLog(@"alertDidEnd called");
}

- (void) showAlert
{
    NSAlert *saveAlert = [[NSAlert alloc] init];

    [saveAlert setAlertStyle:NSWarningAlertStyle];
    [saveAlert setMessageText:messageText];
    [saveAlert setInformativeText:informativeText];
    [saveAlert addButtonWithTitle:defaultButtonTitle];
    [saveAlert addButtonWithTitle:secondButtonTitle];

    [saveAlert beginSheetModalForWindow:[self window]
                        modalDelegate:self
                        didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
                        contextInfo:nil];
}

我自己回答。问题出在applicationShouldTerminate方法的其他地方。

- (NSApplicationTerminateReply )applicationShouldTerminate:(NSApplication *) sender
{   if(conditionOK)
        doSomeStuff;
    else    // all changes are not saved
    {   [self showAlert];
        handleButtonClicked;
    }

    return NSTerminateNow;
}

在if语句的else分支中执行showAlert但也返回“返回NSTerminateNow”。应用程序不会等到警报中单击按钮。它会立即返回。所以我测试了一个尚未发布的响应。

我将修改applicationShouldTerminate方法。

- (NSApplicationTerminateReply )applicationShouldTerminate:(NSApplication *) sender
{   if(conditionOK)
        doSomeStuff;
        return NSTerminateNow;
    else
    {   [self showAlert];
        return NSTerminateCancel;
    }
}

alertDidEnd回调方法将测试返回的按钮,完成工作并在必要时发送终止信号。

目前,我还没有解决问题,但我知道问题出在哪里。

只是一个问题:beginSheetModalForWindow总是异步的,还是只在applicationShouldTerminate的上下文中异步?

1 个答案:

答案 0 :(得分:0)

这是applicationShouldTerminate的最终版本

- (NSApplicationTerminateReply )applicationShouldTerminate:(NSApplication *) sender
{
    if([_buttonSave isEnabled])
    {   if(quitMenuTerminate)
            [self majFile];
        else
        {   [self showAlert];
            return NSTerminateLater;
        }
    }

    return NSTerminateNow;
}

在beginSheetModalForWindow的回调方法alertDidEnd中,我调用了

[[NSApplication sharedApplication] replyToApplicationShouldTerminate:YES];

现在一切都好。