我有一个包含5个项目的数组,也用作tableview的内容。在笔尖中有一个按钮,可以将数组的内容更改为5个不同的项目。但是,当我单击该按钮时,应用程序崩溃并出现EXC_BAD_ACCESS。我在objc_exception _throw上设置了一个断点,并确认了我的怀疑。坏方法是
- (id)tableView:(NSTableView *)wordsTableView
objectValueForTableColumn:(NSTableColumn *)column
row:(int)rowIndex
{
return [[currentCard words] objectAtIndex:rowIndex];
}
currentCard是GameCard类的一个实例,它的数组单词是有问题的数组。在第一次启动时,它工作正常,但如果我尝试更改它,崩溃。
---------- ---------- EDIT
在AppController的awakeFromNib中:我有这个
currentCard = [[GameCard alloc] init];
在按钮的IBAction中,我有这个:
[currentCard release];
currentCard = [[GameCard alloc] init];
启用僵尸后,当我点击按钮时,我从GDB获取此信息:
2009-06-22 18:55:03.368 25WordsMax [19761:813] *** - [CFArray objectAtIndex:]:发送到解除分配的实例0x14ba00的消息
指的是数据源方法。我一直试图追踪内存错误数小时,但我错过了它。
我非常沮丧,我评论了每一个保留&在代码中发布(没有自动释放)仍然得到2009-06-22 19:41:58.564 25WordsMax [21765:813] *** - [CFArray objectAtIndex:]:当我按下按钮时发送到解除分配的实例0x14c330的消息。 / p>
什么是数据源方法?我不是在调用reloadData。如果在我的数据源方法中,我为每行返回@“A Word”,一切运行正常。在GDB中,我甚至可以看到我的NSLogs打印出新数组的内容,一切顺利。只有在调用问题中看到的数据源方法时才会发生任何问题。
答案 0 :(得分:5)
2009-06-22 18:55:03.368 25WordsMax [19761:813] *** - [CFArray objectAtIndex:]:发送到解除分配的实例0x14ba00的消息
仔细阅读。接收者是CFArray的一个实例,消息选择器是objectAtIndex:
。
解除分配的实例是一个数组,而不是游戏卡。
您的游戏卡拥有阵列,因此必须以某种方式保留它。这意味着您必须:
如果您综合了访问者,请将该属性声明为@property(retain)
或@property(copy)
。请注意,如果您想要一个可变副本,这将不起作用;在这种情况下,你必须自己实现setter。
答案 1 :(得分:1)
听起来你在某个地方有一个引用计数错误,这不能仅从那段代码中调试。尝试使用NSZombieEnabled = 1运行,然后查找保留/释放错误,您可以在其中管理任何有关僵尸警告的对象。
答案 2 :(得分:0)
NSZombie告诉你,从[currentCard words]返回的对象正在某处释放,然后你再次使用它。检查对该变量的所有分配,并确保不将其设置为自动释放的对象。然后检查发送给它的所有发布和自动发布消息。
答案 3 :(得分:0)
可能有助于查看GameCard Init和GameCard dealloc方法。
另外要验证您认为问题的方法是问题,我会检查nil
if( [currentCard words] != nil )
return [[currentCard words] objectAtIndex:rowIndex];
else
return @"Blah!";