停止 NSApplication 主事件循环

Stopping the NSApplication main event loop

我有一个包含以下单个 .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 documentation, stop should stop the main loop (run), but it doesn't (at least not on OS X 10.12 and 10.13). There's also terminate,但这会过早退出程序。我还尝试设置一个实现 applicationShouldTerminateNSApplicationDelegate,但这从未被调用过。

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

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

documentation for -stop: 说:

[C]alling this method from a timer or run-loop observer routine would not stop the run loop because they do not result in the posting of an NSEvent object.

分派到主队列的块的相似之处在于它不post一个事件。您可以在调用 -stop:.

后尝试 posting 一个 NSEventTypeApplicationDefined 事件

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

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