You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac Catalyst运行Unity应用时关闭与最小化按钮生命周期回调差异及解决方案

按钮行为差异原因

Mac Catalyst针对iOS应用的窗口生命周期做了原生适配,两个按钮的系统处理逻辑本身存在本质区别:

  • 最小化按钮:仅将窗口隐藏到Dock,应用进程会保留在系统后台挂起队列中,无销毁计划,因此仅触发后台切换回调,不会执行applicationWillTerminate
  • 关闭按钮:系统默认逻辑为触发窗口销毁后终止应用进程,无未完成后台任务时,会在应用切后台后直接调用applicationWillTerminate销毁进程;如果存在未执行完的后台任务,系统会等待任务执行完成后再走销毁流程,这就是你遇到的关闭窗口后不会立刻退出的原因
点击关闭按钮直接退出的实现方案

针对Unity导出的Mac Catalyst Xcode项目,可通过原生层拦截事件实现需求,修改步骤如下:

  1. 找到Unity导出Xcode项目中的UnityAppController.mm文件,先导入AppKit头文件,用平台宏包裹避免iOS端编译报错:
#if TARGET_OS_MACCATALYST
#import <AppKit/AppKit.h>
static BOOL isWindowClosing = NO;
#endif
  1. 在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;
}
  1. 实现窗口关闭的回调方法,修改标记位:
#if TARGET_OS_MACCATALYST
- (void)onWindowWillClose:(NSNotification *)note
{
    isWindowClosing = YES;
}
#endif
  1. 拦截applicationDidEnterBackground回调,判断是关闭窗口触发时直接终止应用,跳过后续后台任务执行:
- (void)applicationDidEnterBackground:(UIApplication*)application
{
#if TARGET_OS_MACCATALYST
    if (isWindowClosing) {
        // 直接终止进程,不会执行后续后台任务
        exit(0);
    }
#endif
    // 原有Unity后台逻辑保留
    ...
}

注意:如果需要更温和的终止方式,可将exit(0)替换为[[UIApplication sharedApplication] terminate:nil],效果一致。

内容的提问来源于stack exchange,提问作者luuuuyang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 00:15:01