1

免责声明:我是 OSX 开发的初学者。

我有一个名为“checkUser”的方法。在该方法中,我需要检查输入的用户凭据是否有效。要检查凭据是否有效,我需要调用一个名为“methodThatInvolvesNetwork”的方法,因为它涉及网络连接,所以它的执行时间可能会有所不同。在“checkUser”中,我需要在“methodThatInvolvesNetwork”运行时显示一个显示进度的警报。用户还可以取消警报,这也将取消正在运行的“methodThatInvolvesNetwork”。
Q1)我应该怎么做?

请注意,必须阻止“checkUser”的执行,并且在“checkUser”中调用“methodThatInvolvesNetwork”。

我目前有这个实现:

- (BOOL)checkUser
{
    NSAlert *alert = [NSAlert alertWithMessageText:@"Sample" defaultButton:@"Okay" alternateButton:nil otherButton:nil informativeTextWithFormat:@""];
    self.alert = alert;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [self methodThatInvolvesNetwork];
    });

    [alert runModal];
    NSLog(@"After run modal");
}

- (void)methodThatInvolvesNetwork
{
    // Do long running task here.

    dispatch_async(dispatch_get_main_queue(), ^{

        if (self.alert != nil)
        {
            [[self.alert window] orderOut:self.alert];
            [[NSApplication sharedApplication] stopModal];
        }
    });
}

Q2)我的实施是否是正确的方法?
Q3)如果是,那么为什么 NSLog(@"After run modal") 在模态警报被解除后很久才执行,而不是在模态警报被解除后立即执行?

4

2 回答 2

1

为了回答我自己的问题,这是我使用的符合要求的:

  • 一个带有 NSWindowController 的 NSWindow。
    此窗口将在加载窗口时在后台运行“methodThatInvolvesNetwork”。

  • 在“checkUser”中,我实例化了上面的窗口“myWindow”,然后将其传递给:

  • Geowar 上面的回答(但没有 didEndSelector):

    [NSApp beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:]

  • 在上面的行之后,我使用以下方式将其作为模态运行:

    [NSApp runModalForWindow:myWindow];

    从而阻止“checkUser”的执行。

  • 当“myWindow”完成时(当 stopModal 或 abortModal 被调用时),“checkUser”的执行将继续。

于 2013-04-04T01:10:15.117 回答
0

[alert runModal] 在警报解除之前不会返回。如果有一个可以将其作为工作表附加到的窗口,那么您应该能够使用 beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo: 它将在警报关闭(而不是阻止)时回调选择器。

于 2013-03-28T22:55:57.513 回答