我的父应用程序使用 helper XPC 来完成一些任务 T1。XPC 服务是使用 NSXPCConnection 实现的。一旦任务完成,我就不需要这个 XPC 还活着。因此,父进程在 NSXPCConnection 对象上调用 invalidate。但是,即使连接无效,XPC 仍然存在。我可以看到它在活动监视器中列出。
当父应用程序仍在运行并且不需要 XPC 处于活动状态时,如何杀死此 XPC?
我的父应用程序使用 helper XPC 来完成一些任务 T1。XPC 服务是使用 NSXPCConnection 实现的。一旦任务完成,我就不需要这个 XPC 还活着。因此,父进程在 NSXPCConnection 对象上调用 invalidate。但是,即使连接无效,XPC 仍然存在。我可以看到它在活动监视器中列出。
当父应用程序仍在运行并且不需要 XPC 处于活动状态时,如何杀死此 XPC?
XPC 代理的设计意味着长期存在。根据 .plist 配置中的 KeepAlive 设置,它们会在退出或崩溃时自动重新加载。
也许您可以注册为 NSWorkspace 事件的观察者:
[[NSWorkspace sharedWorkspace] notificationCenter];
请参阅: NSWorkspace Workspace 通知在以下情况下发布:
然后,您可以在父应用程序退出时禁用 XPC 服务,并在启动时重新启用它。
需要明确的是,当父应用退出时,您的 XPC 进程将退出。至少,我的有。你的问题是:在那之前如何杀死它?
这很简单:只需exit(0)
在调用完成处理程序后立即调用您的 XPC 进程,完成处理程序将输出发送回父应用程序。上个月我需要在一个项目中执行此操作,因为 XPC 进程使用的是 Apple 私有框架,并且退出它是我能想出阻止某些不受欢迎和莫名其妙的唯一方法(因为我没有关于私有框架的文档)副作用。
然而,在退出这个 XPC 进程后,我发现奇怪的是,它继续运行了几毫秒,如果我的父应用程序同时打开了另一个到同一个 XPC 服务的连接,那么注定的 XPC 进程将接受新的连接。杀死自己,让父应用程序挂起。我实际上已经多次看到这种情况发生。
所以,一个后续的问题是:你应该仅仅因为你想变得友善就杀死它吗? 我认为答案是否定的,根据 Apple's Daemons and Services Programming Guide > Creating XPC Services中的以下引用
XPC 服务由 launchd 管理,它按需启动它们,如果它们崩溃则重新启动它们,并在它们空闲时终止它们(通过发送 SIGKILL)。
总结一下:完成后让你的连接失效,让launchd担心被杀。另外,不要屏住呼吸。在过去的两个小时里,我的应用程序一直在运行,而 XPC 进程(最后一个连接在两个小时前关闭)仍在运行。