【问题标题】:Modal NSAlert within block not displayed块内的模态 NSAlert 未显示
【发布时间】:2012-09-23 12:15:43
【问题描述】:

在我的基于文档的应用程序中,我在我的 NSDocumentcontroller 子类中重写了 openDocument: 方法,以便我可以显示我自己的 openPanel。我将选择的 URL 传递给方法 openDocumentWithContentsOfURL:display:completionHandler:。我使用此代码进行通话:

[self openDocumentWithContentsOfURL:[chosenFiles objectAtIndex:i] display:YES completionHandler:^(NSDocument *document, BOOL documentWasAlreadyOpen, NSError *error) {

    if (document == nil)
    {
        NSAlert* alert = [NSAlert alertWithError:error];
        [alert runModal];
    }

}];

所以如果 nil 作为对文档的引用返回,我想显示传递的错误。问题是,在我按下打开面板中的“打开”按钮后,程序只是“冻结”了。然后我需要使用 Xcode 中的“停止”按钮手动停止程序。但是,没有出现旋转的沙滩球。如果我注释“[alert runModal]”行,程序不会再冻结,但当然不会显示警报。

现在奇怪的是:代码有时有效。如果我从 Xcode 切换到我的浏览器并返回并再次运行该程序,它有时会完美运行并显示错误。一段时间后,它再次停止工作。这是不可预测的,但大多数时候它不起作用。

对我来说,这一切听起来像是一种竞争条件。肯定跟区块有关系吧?但是我做错了什么?

【问题讨论】:

  • 可能在主线程上运行模型。 [警报 performSelectorOnMainThread:@selector(runModel) withObject:nil waitUntilDone:NO];
  • 你不想使用[警报节目]吗?
  • @mark:谢谢,这似乎已经解决了。由于错误非常不可预测,我还不能完全确定。为什么必须在主线程上显式执行?
  • @Kyle:NSAlert 没有成员函数“show”。我猜如果还没有窗口,“runModal”是唯一显示它的可能性。
  • @Kyle Tungsten 是对的,我相信你会想到 iOS 的 show 代表 UIAlertView,在 OS X 上你使用 runModal 来显示 NSAlert

标签: objective-c cocoa block nsalert


【解决方案1】:

将我的评论转换为答案:

在主线程上运行模型。

[alert performSelectorOnMainThread:@selector(runModal) withObject:nil waitUntilDone:NO]; 

我认为 runModel 需要在主线程上调用,因为它是 AppKit 框架的一部分,它本质上是触发 UI 图形。我相信对 AppKit 框架或任何操作图形的方法的所有调用都需要在主线程上。

【讨论】:

  • 如何获取Runmodal的返回值。根据按下按钮的返回值,必须进行进一步的阳离子化。请对此发表评论
猜你喜欢
  • 2012-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 2018-06-18
  • 1970-01-01
  • 2022-07-31
  • 1970-01-01
相关资源
最近更新 更多