在initWithCoder中获取EXEC_BAD_ACCESS

时间:2014-01-26 13:41:34

标签: objective-c macos cocoa

我在加载/创建新的视图表单xib文件时遇到问题。我得到EXEC_BAD_ACCESS代码= 2,在我的调用堆栈上,我看到多次调用initWithCoder方法。我不明白为什么会发生这种情况,因为我只为我的类调用了一次alloc init。 在我的代码下面:

@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方法,以及如何修复它?

3 个答案:

答案 0 :(得分:1)

通常,NSView子类不应加载XIB。它们应该是一个XIB(因此在XIB加载时创建)或在代码中创建。

在你的情况下,有许多架构奇怪的东西,但我怀疑崩溃是由于你在scrollTabViewItemWithTableView.xib中有一个SongListView实例,所以当你加载XIB时你运行setup并加载XIB并运行安装程序并加载XIB并运行安装程序......

答案 1 :(得分:0)

您正在尝试将视图添加为自身的子视图:

[self addSubview:self.view];
这样的代码伤害了我的眼睛。您有一个SongListView对象,但您已将其命名为tableView。您已为initWithFrame:定义了初始化工具,但在创建时会向其发送init消息。

答案 2 :(得分:0)

加载nib会在相关类上调用-initWithCoder:并传递self作为所有者将nib中的顶级视图指定为self。您有一个递归,因为每次加载时,您都会尝试再次加载视图。

加载笔尖后,在-initWithCoder:中您的视图已加载,并且您不必加载笔尖或添加子视图。

setup中常见的是一些UI添加,或者其他一些在IB中无法完成的事情。