当[委托]不再被引用时,在`[NSApp run]`中崩溃

Alb*_*ert 1 cocoa objective-c appkit

这是代码:

@interface AppDelegate : NSObject <NSApplicationDelegate>

@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    printf("My app delegate: finish launching\n");
}

@end

int main(int argc, char *argv[])
{
    @autoreleasepool
    {

        [NSApplication sharedApplication];
        [NSApp setDelegate:[[AppDelegate alloc] init]];
        [NSApp run];
    }
}
Run Code Online (Sandbox Code Playgroud)

它崩溃[NSApp run]但我真的没有看到我错过了什么.如果我在[NSApp finishLaunching]之前添加了一个run,它会在那里崩溃.

如果我没有设置委托,它不会崩溃.

如果我之前引用了委托,它可以正常工作:

AppDelegate* appDelegate = [[AppDelegate alloc] init];
[NSApp setDelegate:appDelegate];
Run Code Online (Sandbox Code Playgroud)

所以我想它会因为ARC而在第一个版本中立即释放委托,因为委托可能只是一个弱引用,对吧?但是你应该怎么做相同的代码呢?

Emm*_*uel 5

是的,你猜对了,NSApplication不要保留代表,(弱参考ARC).因此,您可以-fno-objc-arc使用当前代码构建main.m文件:

int main(int argc, char *argv[])
{
    @autoreleasepool
    {
        [NSApplication sharedApplication];
        [NSApp setDelegate:[[AppDelegate alloc] init]];
        [NSApp finishLaunching];
        [NSApp run];
    }
}
Run Code Online (Sandbox Code Playgroud)

或者在main.m中设置AppDelegate static,例如,使用ARC构建

static AppDelegate* _appDelegate;

int main(int argc, char *argv[])
{
    @autoreleasepool
    {
        _appDelegate = [[AppDelegate alloc] init];
        [NSApplication sharedApplication];
        [NSApp setDelegate:_appDelegate];
        [NSApp run];
    }
}
Run Code Online (Sandbox Code Playgroud)