EXC_BAD_ACCESS 为啥我的对象被释放?

Posted

技术标签:

【中文标题】EXC_BAD_ACCESS 为啥我的对象被释放?【英文标题】:EXC_BAD_ACCESS why is my object being deallocated?EXC_BAD_ACCESS 为什么我的对象被释放? 【发布时间】:2013-11-29 08:04:08 【问题描述】:

我正在尝试用一些数据填充 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)

我打开了僵尸,然后对其进行了分析,看起来有问题的行是以下中的 return 语句:

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

分析器在僵尸模式下的输出是: “Objective-C 消息已发送到地址为:bla bla bla 的已释放 'OutlineDataSource' 对象(僵尸)”

如果我在启动僵尸的情况下运行控制台输出,但不配置它是: "[OutlineDataSource outlineView:child:ofItem:]: 消息发送到已释放实例 0xblablabla"

另外两条相关信息:

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

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

所以,很明显我的OutlineSourceData data 对象的引用计数减少到零并被释放。这是在哪里发生的,我该如何阻止它?

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

提前致谢!

【问题讨论】:

初始化后只保留你的数组。 由于我使用的是 ARC,所以无法调用 retain,@utkalpatel。 【参考方案1】:

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

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

OutlineSourceData 设为AppController 类的ivar,而不是awakeFromNib 方法的本地变量。

【讨论】:

呸!你和你喜欢的“文档”。 所以,我实际上已经在文档中阅读了该行。问题是我来自 Java,它不关心关于引用的两个 sh*ts,所以当它说“弱引用”时我没有密切注意。 这是 ARC 掩盖事物的方式之一。在引用计数内存管理的时代,这类错误更容易被发现。

以上是关于EXC_BAD_ACCESS 为啥我的对象被释放?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在构造函数中释放会导致 EXC_BAD_ACCESS?

如果我不再使用它,为啥在释放 MKMapView 后我会崩溃?

为啥我的自动释放对象没有被释放?

为啥我的 Chrome Profiler 没有为我的对象显示正确的保留路径,为啥我的对象从未被释放?

释放自动释放对象不会使我的应用程序崩溃,为啥?

释放对象导致 exc_bad_access