Tom*_*und 8 memory iphone objective-c
我有一个神秘地解除分配的Objective-C对象(在iOS游戏应用程序中)的问题.
该对象是一个GameCharacter实例,它实例化如下:
for (int c = 0; c < kNrOfGuards; c++) {
GameCharacter* guard = [[GameCharacter alloc] initGuard:self sprite:guardSprite];
[characterArray addObject:guard];
[guard release];
}
Run Code Online (Sandbox Code Playgroud)
我还有一个方便的方法来查找GameCharacter:
- (GameCharacter*)findCharacterWithIndex:(int)index {
return [characterArray objectAtIndex:index];
}
Run Code Online (Sandbox Code Playgroud)
生成错误的代码如下所示:
for (int c = 0; c < [self characterCount]; c++) {
GameCharacter* tempCharacter = [self findCharacterWithIndex:c];
if (tempCharacter.playerId == playerIndex]) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
运行此代码一段时间(从不立即)会在控制台中生成错误:
[GameCharacter playerId]:发送到解除分配的实例0x4e47560的消息
使用NSZombieEnabled技巧,我设法找到导致问题的对象,但我仍然无法理解为什么要解除分配此对象.在我的代码中搜索"release"/"dealloc"不会产生任何线索.
我已经尝试删除"释放"(甚至添加"保留"!)到alloc/init循环(参见顶部),它似乎延长了应用程序可以运行的时间但不能完全解决问题.
任何提示将不胜感激!
编辑
感谢quixoto,Olie,Eiko,tc.,我发现它是我的GameCharacter对象正被释放,但我仍然不明白为什么.以下是反向时间顺序的跟踪日志:
#0 -[GameCharacter dealloc]
#1 objc_setProperty
#2 -[TiledGroundLayer setSelectedCharacter:]
#3 -[TiledGroundLayer selectNextCharacterForPlayer:searchStep:]
#4 -[GameScene selectNextCharacter:]
#5 -[GameScene endTurn]
#6 -[HUDLayer onClickDone:]
Run Code Online (Sandbox Code Playgroud)
这里发生的是,用户单击"完成",屏幕上的所选字符被更改,因此selectedCharacterTiledGroundLayer上的属性被更改(步骤#2-4).由于selectedCharacter拥有以前的GameCharacter对象,它似乎正在被释放.但为什么NSMutableArray([characterArray addObject:guard];)没有正确保留它?
根据您的更新:
#0 -[GameCharacter dealloc]
#1 objc_setProperty
#2 -[TiledGroundLayer setSelectedCharacter:]
Run Code Online (Sandbox Code Playgroud)
我猜想您正在释放对 setter 中对象的现有引用,然后保留新副本。但是,如果新对象恰好与现有引用完全相同,则您可能会将消息发送retain到已释放的对象。
-(void) setSelectedCharacter: (GameCharacter*) newCharacter
{
[character release]; // Oops if character == newCharacter
character = [newCharacter retain];
}
Run Code Online (Sandbox Code Playgroud)