2012-08-05 36 views
2

我想開發一個簡單的應用程序,它通過單擊一個菜單項時顯示一個包含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

preferencesWindow = [[[PreferencesWindowController alloc] initWithWindowNibName:@"PreferencesWindow"] window]看起來很可疑,因爲當你引用窗口本身具有很強的參考性,看起來你讓ARC發佈PreferencesWindowController

嘗試將PreferencesWindowController對象存儲在自己的strong變量/屬性中,並讓我知道。

+0

謝謝,那就是問題! 我已經把那個(窗口控制器,實際上)變成只讀懶惰加載屬性 – fferri 2012-08-05 23:50:16

+0

@mescalinum太棒了!很高興它對你有效。 – Vervious 2012-08-05 23:54:32