如何以编程方式关闭窗口的NSAlert运行模式

Jer*_*son 0 cocoa objective-c

线程1运行模态警报:

- (void)didEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
{
[sheet orderOut:self];
};


-(void)newAlert
{
currentAlert=[NSAlert alertWithMessageText:@"Switch drives!" defaultButton:@"Cancel sync" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Please switch disks: %@",reason,nil];
[currentAlert setDelegate:self];
[currentAlert beginSheetModalForWindow:self.window completionHandler:^(NSInteger returnCode)
            {
                mustStop=TRUE;
            }];

}     
Run Code Online (Sandbox Code Playgroud)

在其他地方,在另一个线程上我想解除警报,但这不起作用:

[NSApp endSheet:[self window]];
Run Code Online (Sandbox Code Playgroud)

这是行不通的.

Ken*_*ses 5

您无法在后台线程上执行GUI操作.你必须在主线程上执行它们.所以,你可以这样做:

dispatch_async(dispatch_get_main_queue(), ^{
    [NSApp endSheet:self.window];
});
Run Code Online (Sandbox Code Playgroud)

但从技术上讲,您应该使用新的工作表方法NSWindow.所以,你应该这样做:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.window endSheet:currentAlert.window];
});
Run Code Online (Sandbox Code Playgroud)

当然,这意味着您需要跟踪-newAlert方法之外的警报.(我想你可以使用,self.window.attachedSheet如果你没有跟踪警报,虽然可能存在竞争条件,其中后台线程取消与警报不同的工作表.)

此外,-didEndSheet:returnCode:contextInfo:使用时运行警报时不使用该方法-beginSheetModalForWindow:completionHandler:.