Cocoa,控制器实例化和崩溃

时间:2012-08-05 22:55:44

标签: objective-c cocoa crash

我正在尝试开发一个简单的应用程序,在单击菜单项时,它会显示一个包含NSTableView的窗口。 问题是应用程序在NSTableView显示数据后崩溃。完整堆栈跟踪:

* thread #1: tid = 0x2107, 0x00007fff943bce90 libobjc.A.dylib\`objc_msgSend + 16,
             stop reason = EXC_BAD_ACCESS (code=13, address=0x0)
  frame #0: 0x00007fff943bce90 libobjc.A.dylib`objc_msgSend + 16

由于我使用ARC,我应该排除任何引用计数问题;但也许我正在以一种糟糕的方式创建控制器(需要创建窗口),并且它被错误地免费提供。

这是创建并显示窗口的 AppController 的代码:

- (IBAction)showPreferences:(id)sender {
    if(!preferencesWindow) {
        preferencesWindow = [[[PreferencesWindowController alloc]
                          initWithWindowNibName:@"PreferencesWindow"] window];
    }

    [preferencesWindow makeKeyAndOrderFront:sender];
}

PreferencesWindowController 中的此代码实现了dataSource协议(NSTableView所需)。

- (int)numberOfRowsInTableView:(NSTableView *)tabView {
    return 1;
}

- (id)tableView:(NSTableView *)tabView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row {
    NSString *val = [NSString stringWithFormat:@"%@[%d]", [tableColumn identifier], row];
    return val;
}

这不会导致崩溃本身。但是如果我从NSTableView的dataSource中删除PreferencesWindowController,它就不会崩溃,所以它应该有些相关。

哪里出错?

编辑:使用具有预设僵尸的探查器(乐器),我可以看到有一个对象的参考计数器变为负数:

screenshot of Instruments

但无论如何,堆栈超出了我编写的代码。我不能在那里放一个断点,我看不出哪个是被释放的对象(或者我应该说我不知道​​怎么做)

1 个答案:

答案 0 :(得分:1)

preferencesWindow = [[[PreferencesWindowController alloc] initWithWindowNibName:@"PreferencesWindow"] window]看起来很可疑,因为当您使用强引用引用窗口本身时,看起来您正在让ARC释放PreferencesWindowController

尝试将PreferencesWindowController对象存储在自己的strong变量/属性中,并告诉我们。