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

启用ARC时无xib/storyboard的macOS应用关闭窗口崩溃问题

问题根因

崩溃的核心原因是ARC环境下AppDelegate实例无强引用持有,被提前释放引发野指针:
NSApplication的delegate属性为弱引用(官方定义为@property (nullable, weak) id<NSApplicationDelegate> delegate;),弱引用不会增加对象引用计数,无法保证对象生命周期。
你在main.m中创建AppDelegate实例后直接赋值给delegate,没有任何其他强引用指向该实例,ARC会在赋值表达式结束后自动回收这个临时对象。后续App运行、关闭窗口触发终止流程时,NSApplication尝试向已经被释放的delegate发送回调消息,就会抛出EXC_BAD_ACCESS野指针错误。这也完全匹配你观察到的「仅开启ARC时崩溃」的现象:MRC模式下没有自动回收机制,创建的对象不会被主动释放,就不会触发该问题。
你之前尝试过用setDelegate:方法赋值但没有效果,和调用方式无关,本质是没有强引用托住AppDelegate实例。另外你写的(AppDelegate *){[[AppDelegate alloc] init]}复合字面量写法,在ARC下不会生成强引用持有临时对象,也会加剧这个问题。

修复方法

只需要保证AppDelegate实例在App整个运行生命周期内被强引用持有即可,最简洁的实现是修改main.m,用强类型的局部变量持有delegate:

#import <Cocoa/Cocoa.h>
#import "AppDelegate.h"
int main(void) {
    @autoreleasepool {
        // 局部变量默认是__strong强引用,会在整个@autoreleasepool生命周期内持有对象
        AppDelegate *appDelegate = [[AppDelegate alloc] init];
        NSApplication *app = [NSApplication sharedApplication];
        app.delegate = appDelegate;
        [app run];
    }
    return 0;
}

修改后appDelegate会在[NSApp run]整个执行周期(也就是从App启动到完全终止的全流程)里被强持有,不会被提前释放,关闭窗口时的回调就能正常触发,应用会按预期终止不会崩溃。

额外说明:你在applicationDidFinishLaunching:中创建的NSWindow不会有同类问题,调用makeKeyAndOrderFront:后系统会把窗口加入NSApplication的window列表,被系统强持有,不会提前释放。唯一不规范的点是makeKeyAndOrderFront:的sender参数传了窗口自身,这个参数代表触发方法的调用者,传nil即可,不影响运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:27:25