当TableView的DataSource阵列发生变化时,应用程序崩溃

Wal*_*ker 2 cocoa objective-c

我有一个包含5个项目的数组,也用作tableview的内容.在笔尖中有一个按钮,可以将数组的内容更改为5个不同的项目.但是,当我单击该按钮时,应用程序崩溃并出现EXC_BAD_ACCESS.我在objc_exception _throw上设置了一个断点,并确认了我的怀疑.糟糕的方法是

- (id)tableView:(NSTableView *)wordsTableView
objectValueForTableColumn:(NSTableColumn *)column
            row:(int)rowIndex
{
    return [[currentCard words] objectAtIndex:rowIndex];
}
Run Code Online (Sandbox Code Playgroud)

currentCard是GameCard类的一个实例,它的数组,单词,是有问题的数组.在第一次启动时,它工作正常,但如果我尝试更改它,崩溃.

- - - - - 编辑 - - - - -

在AppController的awakeFromNib中:我有这个

currentCard = [[GameCard alloc] init];
Run Code Online (Sandbox Code Playgroud)

在按钮的IBAction中,我有这个:

[currentCard release];
currentCard = [[GameCard alloc] init];
Run Code Online (Sandbox Code Playgroud)

启用僵尸后,当我单击按钮时,我从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.

什么是数据源方法?我不是在调用reloadData.如果在我的数据源方法中,我为每行返回@"A Word",一切运行正常.在GDB中,我甚至可以看到我的NSLogs打印出新数组的内容,一切顺利.只有在问题中看到的数据源方法被调用时才会发生任何问题.

Pet*_*sey 5

2009-06-22 18:55:03.368 25WordsMax [19761:813]*** - [CFArray objectAtIndex:]:发送到解除分配的实例0x14ba00的消息

仔细阅读.接收者是CFArray的一个实例,消息选择器是objectAtIndex:.

解除分配的实例是一个数组,而不是游戏卡.

您的游戏卡拥有阵列,因此必须以某种方式保留它.这意味着您必须:

  1. 使用alloc和init创建数组(而不是自动释放它).
  2. 保留它.
  3. 制作自己的副本.(如果你从另一个对象接收一个数组,就像在你的setter中一样,因为你收到的数组可能是可变的,并且你不希望另一个对象改变"你的"数组.)

如果您合成了访问者,请将该属性声明为@property(retain)@property(copy).请注意,如果您想要一个可变副本,这将不起作用; 在这种情况下,你必须自己实现setter.