У меня есть приложение, состоящее из следующего единственного файла .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;
}
Согласно документации разработчика, stop
должен остановить основной цикл (run
), но это не так (по крайней мере, не в OS X 10.12 и 10.13). Также есть terminate
, но он тоже выходит из программы скоро. Я также пробовал установить NSApplicationDelegate
, реализующий applicationShouldTerminate
, но он никогда не вызывается.
Как я могу убедиться, что основной цикл выполнения (чисто) завершен?
Примечание. Основной цикл общего приложения необходим, поскольку пользовательский интерфейс выполняется где-то еще. Более конкретно, это создает проблемы в библиотеке пользовательского интерфейса Go WDE, которая использует Какао для предоставления окно в приложение Go.
2 ответа
В документации для -stop:
говорится:
[C] использование этого метода из таймера или подпрограммы наблюдателя цикла выполнения не остановит цикл выполнения, потому что они не приводят к отправке объекта NSEvent.
Блок, отправленный в основную очередь, аналогичен тому, что он не публикует событие. Вы можете попробовать опубликовать событие NSEventTypeApplicationDefined
после вызова -stop:
.
После дальнейшего исследования выяснилось, что запрос цикла пользовательского интерфейса stop
обрабатывается только после события UI (а не сразу после события основного цикла). Итак, он работает в ответ на событие пользовательского интерфейса, но не в потоке, как в моем примере.
Запуск события пользовательского интерфейса после запроса stop
(например, для меня работает программное изменение размера) приводит к завершению цикла.
Новые вопросы
objective-c
Этот тег следует использовать только для вопросов, касающихся функций Objective-C или зависящих от кода на языке. Теги [cocoa] и [cocoa-touch] следует использовать, чтобы узнать о фреймворках или классах Apple. Используйте связанные теги [ios], [macos], [apple-watch] и [tvos] для проблем, характерных для этих платформ.