Resloved!
感谢Lone Gunman,这个问题是由于在发布之前没有将许多代表设置为nil的疏忽。
这是一个奇怪的...我熟悉基本的内存管理,但我认为我所看到的东西是不寻常的。这是一个小背景......
我有一个NavigationController,用于处理以下ViewControllers之间的导航:
主页 - >游戏 - >游戏
当运行代码时,它在离开游戏时会崩溃。在GameViewController中有一个类似于:
的dealloc方法- (void)dealloc
{
[board release];
[opponentsViewController release];
[instructionsViewController release];
[imgPicker release];
[gameView release];
[super dealloc];
}
当导航控制器返回游戏列表(从游戏中)时,它会抛出EXC_BAD_ACCESS。所以我提出了我可信赖的探查器并检查僵尸。唉,就像我预期的那样,一条消息被发送到一个解除分配的对象!深入挖掘我发现对象的历史中有3个条目:
从UINavigationController setDisappearingViewController调用调用2和3。
在我的dealloc方法中,我为每个释放调用设置了断点,当这样做时 - 发生[board release]调用,然后发生[opponentsViewController release]调用,然后再次发生[board release]调用。所以我看到dealloc方法没有完全完成并再次调用。
可能导致这种情况的原因是什么?
修改:这是GameViewController Implementation
添加此游戏的游戏控制器代码:
-(void) gotoGame:(int)tag {
game = [[GameViewController alloc] init];
[self.navigationController pushViewController:game animated:YES];
[game release];
}
答案 0 :(得分:3)
我会尝试将你所有的ivar代表设置为nil(编辑:在dealloc中)。我对获取的结果控制器有类似的问题。无法在dealloc中将其委托设置为nil,并且在释放视图控制器时,核心数据堆栈仍然具有指向它的指针。
所以这是我的赌注,将ivar代表设置为dealloc中的nil,虽然我看不到你的标题知道你所遵循的协议是什么。
编辑:解释
设置委托实际上是为正在执行委托的对象提供指针(我相信它通常是指定的属性)。
@property (assign) delegate;
我将以我所遇到的问题为例。
所以假设你有一个视图控制器,它有一个fetchedResultsController作为一个ivar。设置FRC委托时:
fetchedResultsController.delegate = self;
并且视图控制器被释放,任何使用该指针的对象仍然认为它是活的。你会想到,因为FRC也会在dealloc中发布,你会很好(这就是为什么花了4天时间来解决这个问题:)),但有时候实现的其他部分也会使用你的委托。所以修复是:
-(void)dealloc
{
self.fetchedResultsController.delegate = nil;
[_fetchedResultsController release];
[super dealloc];
}
注意:只要新工具可供所有人使用,您就不用再担心这些东西^ ^;
答案 1 :(得分:-3)
尝试
- (void) dealloc {
if(game != nil){
//release here
[game release];
}
[super dealloc];
}
顺便说一下,你似乎已经在头文件中声明游戏,并且在推送之后你正在释放它,并且在dealloc方法中你正在释放它。从dealloc方法中删除释放调用或更改这样的方法。
-(void) gotoGame:(int)tag {
GameViewController *game = [[GameViewController alloc] init];
[self.navigationController pushViewController:game animated:YES];
[game release];
}
<强>更新强>
此外,您没有在任何地方使用该标签。为什么不像这样创建你的init方法
GameViewController *game = [[GameViewController alloc] initWithTag:tag];
[self.navigationController pushViewController:game animated:YES];
[game release];