问题
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