Mac Catalyst运行Unity应用时关闭与最小化按钮生命周期回调差异及解决方案
按钮行为差异原因
Mac Catalyst针对iOS应用的窗口生命周期做了原生适配,两个按钮的系统处理逻辑本身存在本质区别:
- 最小化按钮:仅将窗口隐藏到Dock,应用进程会保留在系统后台挂起队列中,无销毁计划,因此仅触发后台切换回调,不会执行
applicationWillTerminate - 关闭按钮:系统默认逻辑为触发窗口销毁后终止应用进程,无未完成后台任务时,会在应用切后台后直接调用
applicationWillTerminate销毁进程;如果存在未执行完的后台任务,系统会等待任务执行完成后再走销毁流程,这就是你遇到的关闭窗口后不会立刻退出的原因
点击关闭按钮直接退出的实现方案
针对Unity导出的Mac Catalyst Xcode项目,可通过原生层拦截事件实现需求,修改步骤如下:
- 找到Unity导出Xcode项目中的
UnityAppController.mm文件,先导入AppKit头文件,用平台宏包裹避免iOS端编译报错:
#if TARGET_OS_MACCATALYST #import <AppKit/AppKit.h> static BOOL isWindowClosing = NO; #endif
- 在
application:didFinishLaunchingWithOptions:方法的末尾添加窗口关闭通知监听:
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { // 原有Unity初始化逻辑保留 ... #if TARGET_OS_MACCATALYST // 监听窗口关闭事件 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onWindowWillClose:) name:NSWindowWillCloseNotification object:nil]; #endif return YES; }
- 实现窗口关闭的回调方法,修改标记位:
#if TARGET_OS_MACCATALYST - (void)onWindowWillClose:(NSNotification *)note { isWindowClosing = YES; } #endif
- 拦截
applicationDidEnterBackground回调,判断是关闭窗口触发时直接终止应用,跳过后续后台任务执行:
- (void)applicationDidEnterBackground:(UIApplication*)application { #if TARGET_OS_MACCATALYST if (isWindowClosing) { // 直接终止进程,不会执行后续后台任务 exit(0); } #endif // 原有Unity后台逻辑保留 ... }
注意:如果需要更温和的终止方式,可将
exit(0)替换为[[UIApplication sharedApplication] terminate:nil],效果一致。
内容的提问来源于stack exchange,提问作者luuuuyang
相关产品推荐
相关产品推荐

