【问题标题】:Stopping the NSApplication main event loop停止 NSApplication 主事件循环
【发布时间】:2017-12-31 09:08:06
【问题描述】:

我有一个包含以下单个 .m 文件的应用程序:

#import <Cocoa/Cocoa.h>

int main(int argc, char* argv[]) {
  [[[NSThread alloc] initWithBlock: ^{
    sleep(2);
    dispatch_async(dispatch_get_main_queue(), ^{ 
      NSLog(@"Stop");
      [[NSApplication sharedApplication] stop:nil];
    });
  }] start];
  [[NSApplication sharedApplication] run];
  NSLog(@"Run finished");
  return 0;
}

根据the developer documentationstop 应该停止主循环 (run),但它不会(至少在 OS X 10.12 和 10.13 上不会)。还有terminate,但是这个退出程序太快了。我还尝试设置一个实现applicationShouldTerminateNSApplicationDelegate,但这从未被调用过。

如何确保主运行循环(干净)退出?

注意: 共享应用程序主循环是必要的,因为 UI 工作正在其他地方完成。更具体地说,这给Go WDE UI 库带来了问题,它使用 Cocoa 为 Go 应用程序提供一个窗口。

【问题讨论】:

  • 没有足够的上下文来回答这个问题。即兴发挥,如果你正在编写一个命令行工具,它应该被构造成一个命令行工具,并且根本不使用 NSApplication。
  • @bbum 我没有添加任何上下文,因为它似乎与问题无关,只会使问题复杂化。无论如何,添加了请求的上下文。

标签: objective-c cocoa nsapplication


【解决方案1】:

documentation for -stop: 说:

[C]从计时器或运行循环观察程序调用此方法不会停止运行循环,因为它们不会导致 NSEvent 对象的发布。

分派到主队列的块是相似的,因为它不发布事件。您可以尝试在调用-stop: 后发布NSEventTypeApplicationDefined 事件。

【讨论】:

    【解决方案2】:

    在进一步调查之后,似乎 UI 循环 stop 请求仅在 UI 事件之后处理(因此不仅仅是在主循环事件之后)。因此,它可以响应 UI 事件,但不像我在示例中那样在线程中工作。

    stop 请求后触发 UI 事件(例如,程序化调整大小对我有用)会导致循环结束。

    【讨论】:

      猜你喜欢
      • 2010-10-22
      • 2014-01-01
      • 2020-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 2011-10-07
      相关资源
      最近更新 更多