2014-01-26 80 views
0

加載/創建新視圖窗體xib文件時出現問題。我得到EXEC_BAD_ACCESS代碼= 2,在我的調用堆棧上,我看到多次調用initWithCoder方法。我不明白爲什麼會發生這種情況,因爲我只爲我的類調用alloc init一次。 下面我的代碼:在initWithCoder中獲取EXEC_BAD_ACCESS

@interface SongListView : NSView 
@property (nonatomic, strong) IBOutlet NSScrollView* view; 
@end 

@implementation SongListView 

- (id)initWithFrame:(NSRect)frameRect 
{ 
    self = [super initWithFrame:frameRect]; 

    if(self) 
    { 
     [self setup]; 
    } 
    return self; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder: aDecoder]; 

    if(self) 
    { 
     [self setup]; 
    } 

    return self; 
} 

- (void)setup 
{ 
    NSArray *nib; 

    [[NSBundle mainBundle] loadNibNamed:@"scrollTabViewItemWithTableView" 
            owner:self 
         topLevelObjects:&nib]; 
    [self addSubview: self.view]; 
} 

@end 

,這是我創建SongListView:

SongListView* tableView = [[SongListView alloc] init]; 

有人可以解釋我發生了什麼,爲什麼我得到多發呼叫的initWithCoder方法,以及如何解決它?

回答

0

您嘗試添加視圖作爲自身的一個子視圖:

[self addSubview:self.view]; 

代碼這樣傷害我的眼睛。您有一個SongListView對象,但您已將其命名爲tableView。您已經爲initWithFrame:定義了一個初始化程序,但是您在創建它時發送了init消息。

+0

本身,'-init'很好,因爲它與CGREctZero相當於'initWithFrame:'。不過,接下來會發生一些混亂。 – coverback

0

加載筆尖導致在相關類上調用-initWithCoder:並傳遞self,因爲所有者將筆尖中的頂層視圖指定爲self。你有一個遞歸,因爲對於每個負載,你嘗試再次加載視圖。

一旦你加載了筆尖,在-initWithCoder:你的視圖已經加載,你不必加載筆尖或添加子視圖。

setup通常會出現的一些UI增加或其他一些無法在IB中完成的事情。

+0

擁有「自己」作爲所有者通常很好。這就是你如何將IBOutlets和IBActions連接到「文件所有者」。 –

+0

@WilShipley在這種情況下是不是自己的文件的所有者?如果沒有這個參數,nib加載器將不知道要附加哪個實例。 – coverback

+0

是的,這是正確的,但我不認爲「initWithCoder:」被稱爲是因爲這個引用自我。我想,第二段指出了這個問題。 –

1

通常你的NSView子類不應該加載XIB。它們應該是在XIB中(並且因此在XIB加載時創建)或者在代碼中創建。

在你的情況下,存在一些架構上奇怪的事情,但我懷疑崩潰是由scrollTabViewItemWithTableView.xib中的SongListView實例引起的,所以當你加載XIB時運行安裝程序並加載XIB並運行安裝程序並加載XIB並運行安裝程序並...