EXC_BAD_ACCESS为什么我的对象被解除分配?

时间:2013-11-29 08:04:08

标签: objective-c macos xcode5

我正在尝试用一些数据填充NSOutlineView。我已经创建了一个包装数据的类。

(我正在使用ARC,并使用xcode 5.0.2)

.h文件:

@interface OutlineDataSource : NSObject <NSOutlineViewDataSource>{
    NSArray *theData;
}

- (id)initWithArray:(NSArray*)array;
@end

.m文件

@implementation OutlineDataSource
- (id)initWithArray:(NSArray *)array{
    self = [super init];
    theData = array;
    return self;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item{
    return [theData objectAtIndex:index];
}

...some other mandatory methods here...

@end

然后在我的awakeFromNib中,在AppController类中,我这样使用它:

...
NSArray *theArray = [NSArray arrayWithObjects:@"Foo", @"Bar", nil];
OutlineDataSource *data = [[OutlineDataSource alloc]initWithArray:theArray];
[teachersSelectOutline setDataSource:data];//the name of the NSOutlineView is "teachersSelectOutline"
...

应用程序以EXC_BAD_ACCESS终止(代码= 1,地址= bla bla bla)

我打开了僵尸,然后对它进行了分析,看起来违规的行是以下的返回语句:

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item{
    return [theData objectAtIndex:index];
}

僵尸模式中探查器的输出是: “一个Objective-C消息被发送到一个解除分配的'OutlineDataSource'对象(僵尸),地址为:bla bla bla”

和控制台输出,如果我用僵尸打开它,但不要分析它是: “[OutlineDataSource outlineView:child:ofItem:]:发送到解除分配的实例0xblablabla的消息”

另外两个相关信息:

1)如果不是使用我的initWithArray方法,而是使用基本的init方法,我只是将theData初始化为空数组,错误消失,应用程序运行正常。< / p>

2)如果我在AppController类中实现了所有完全相同的代码,那么错误也会消失,应用程序运行正常。

因此,显然我的OutlineSourceData data对象将其引用计数减少到零并被取消分配。这是怎么回事,怎么能阻止呢?

(或者,我错过了其他什么?)

提前致谢!

1 个答案:

答案 0 :(得分:2)

您可能遇到崩溃,因为正在按预期释放OutlineSourceData实例。您创建实例并将其分配给NSOutlineView,但大纲视图仅保留对数据源的弱引用。

根据setDataSource:方法documentation“接收方维护对数据源的弱引用”

OutlineSourceData设为AppController课程的ivar,而不是awakeFromNib方法的本地。