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 为啥我的对象被释放?的主要内容,如果未能解决你的问题,请参考以下文章
如果我不再使用它,为啥在释放 MKMapView 后我会崩溃?