Stopping the NSApplication main event loop

限于喜欢 提交于 2021-01-27 19:20:02

问题


I have an application consisting of the following single .m file:

#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;
}

According to 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, but this exits the program too soon. I also tried setting an NSApplicationDelegate that implements applicationShouldTerminate, but this is never called.

How can I make sure the main run loop is (cleanly) exited?

Note: The shared application main loop is necessary because there is UI work being done elsewhere. More concretely, this is giving problems in the Go WDE UI library, which uses Cocoa to provide a window to a Go application.


回答1:


The documentation for -stop: says:

[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.

A block dispatched to the main queue is similar in that it doesn't post an event. You can try posting an NSEventTypeApplicationDefined event after calling -stop:.




回答2:


After investigating this further, it seems that the UI loop stop request is only processed after a UI event (so not just after a main loop event). So, it works in response to a UI event, but not in a thread like I did in my example.

Triggering a UI event after a stop request (e.g. a programmatic resize works for me) causes the loop to end.



来源:https://stackoverflow.com/questions/48041279/stopping-the-nsapplication-main-event-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!