Как правильно завершить работу службы MacOS XPC?
Я успешно следовал учебному руководству Daemons and Service Guide - Создание служб XPC, а также SandboxedFetch
образец кода и иметь рабочую настройку клиента / службы, которая использует новый NSXPCConnection
учебный класс.
Для меня все еще не совсем ясно, как правильно завершить работу приложения-службы, когда оно завершит свою работу. Я признаю, что во многих случаях ожидается, что служба останется работоспособной, но в моем сценарии использования служба будет использоваться только для выполнения некоторой обработки, которую в противном случае я бы не выполняла в основном приложении. Как только эта обработка завершена, нет никаких оснований для того, чтобы приложение-служба оставалось. Если клиенту понадобится другой сервис позднее, он может просто заново создать новый.
Так как услуга легкая, не заостренная, NSApplication
Я пытался завершить его, позвонив invalidate
изнутри applicationWillTerminate
, но это вызывает исключение EXC_BAD_ACCESS почти каждый раз. призвание invalidate
на службе [NSXPCListener serviceListener]
генерирует чуть менее надежные сбои, но все равно сбои.
призвание invalidate
из клиентского приложения на его NSXPCConnection
также генерирует исключение EXC_BAD_ACCESS почти каждый раз.
Поэтому мне любопытно, какова правильная последовательность шагов, чтобы аккуратно завершить работу службы XPC и затем выйти из приложения службы. В идеале служба должна завершать свою работу после того, как она сделала последний вызов XPC клиенту.
Прилагается небольшой скриншот того, как выглядит одна из трассировок стека исключения. (Да, это веб-просмотр, который загружается в сервис. Как только веб-просмотр завершит загрузку, я хочу, чтобы сервис завершал свою работу)
1 ответ
Моя первая реакция заключается в том, что вы не должны беспокоиться, чтобы прекратить. Когда происходит нехватка памяти и ваш сервис бездействует, launchd убьет ваш сервис. Выход, вероятно, не в чьих-либо интересах, потому что запуск вашего сервиса займет некоторое время. Не прекращайте, и вам не придется выяснять, почему ваша попытка не удалась.
Но если по какой-то причине вы решили прекратить, не пытайтесь так сильно. Просто сделайте все, что вам нужно, чтобы очистить (очистить буферы, корректно закрыть сетевые соединения, чтобы сервер не пострадал) и вызвать выход. Хотя вы, похоже, используете NSApplication, ваш сервис не является приложением в каком-то смысле, который волнует пользователя, и нет веских причин действовать как один в этом отношении. В любом случае хост-приложение должно справиться с тем, что ваш сервис будет аварийно завершать работу, поэтому ваш преднамеренный бесцеремонный выход - это просто замечательно.
Кстати, использование NSApplication в службе XPC, вероятно, не лучшая идея, потому что нет поддерживаемого способа заявить, что вы этого хотите. Это может помочь объяснить, почему это не работает так, как вам хотелось бы, хотя этот абзац не следует рассматривать как надлежащий анализ сбоя.:-)