背景信息:我创建一个SpriteKit 2D平台式的游戏多“地板”。 当用户进入一个“门户”,他被输送到另一楼层(一方或向上一个向下)。 如果用户去世,享年从那里最近的spawnpoint是不同的楼层,他被运回与spawnpoint地板。
问题:升级到iOS8上后,这种情况会导致游戏的崩溃EXC_BAD_ACCESS
异常/错误。 即使通过关于如何调试这样的错误多个教程去后,我似乎无法找出问题所在。
所以,我会很感激,如果有人可以看看我的代码,并告诉我,如果他们看到做我在做什么更好的办法,最好不导致游戏冻结。
游戏布局:我有一个自定义类TileMapLayer
这是基于从雷Wenderlich的书的iOS游戏通过教程同一类。 它基本上是一个包含多个32x32p瓷砖定制SKNode类,结合创建我的游戏背景。
我加载相应的地板在游戏开始的时候,然后调用加载另一个楼层时,我的用户进入向上/向下。 在这种情况下,我缓存当前地板首先在NSDictionary
,所以我可以当用户返回到该楼层日后访问。
// Cache the current floor
[_allFloors setObject:_bgLayer forKey:[NSString stringWithFormat:@"floor_%tu", (unsigned)_currentFloor]];
// Remove the current floor
[_bgLayer removeFromParent];
// Get the cached (next) floor if it exists, if not create it
TileMapLayer *cachedFloor = [_allFloors objectForKey:[NSString stringWithFormat:@"floor_%tu", (unsigned)(_currentFloor + 1)]];
if (!cachedFloor) {
_bgLayer = [self createScenery:[NSNumber numberWithInteger:(_currentFloor + 1)]];
NSLog(@"creating new floor");
} else {
_bgLayer = cachedFloor;
NSLog(@"getting cached floor");
}
// Display the new floor
[_worldNode addChild:_bgLayer];
// Increment the floor number
_currentFloor++;
(我有下降地板以及类似的方法)。 这完美的作品,之前和升级到iOS8上后。
当用户去世,他被运回最后spawnpoint。 如果最后spawnpoint是在不同的楼层,地板也相应发生变化。 我呼吁球本身作为动画的一部分,这个自定义SKAction:
SKAction *changeFloor = [SKAction runBlock:^{
if (self.spawnFloor != _currentFloor) {
[_bgLayer removeFromParent];
_bgLayer = [_allFloors objectForKey:[NSString stringWithFormat:@"floor_%tu", (unsigned)self.spawnFloor]];
[_worldNode addChild:_bgLayer];
_currentFloor = self.spawnFloor;
NSLog(@"Made it here");
}
}];
正如你所看到的没有太大的区别。 将Made it here
被记录到控制台,但在比赛结束后立即冻结。 下一个方法我称之为(把球移动到正确的位置)不执行的。
只是为了好玩我试图缓存_bgLayer
从其父像这样删除之前:
if (self.spawnFloor != _currentFloor) {
[_allFloors setObject:_bgLayer forKey:[NSString stringWithFormat:@"floor_%tu", (unsigned)_currentFloor]];
...
出于某种原因,我做这个游戏时不会冻结。 然而,地板最终被混合仿佛_bgLayer
从来没有从其父删除(注:“旧的”瓷砖也不再响应任何物理的仿真,他们只是在后台无所事事)。
我还试图[_bgLayer removeAllChildren]
从父除去之后(除去各个铺砌):
[_bgLayer removeFromParent];
[_bgLayer removeAllChildren];
但是,这会导致_bgLayer当我重生后回到这一层楼是空的。 就好像我删除了所有的节点之前,我保存它在字典中。 我的猜测是,只有字典引用_bgLayer的位置,而不是内容本身。 所以,当我删除所有的孩子在屏幕上,能有效地去除所有的人都在缓存。
结束语:我知道这是一个长期的问题,我想说谢谢你,如果你做了这一步。 如果您有任何问题,请不要犹豫,问他们在下面的意见。 最后,我想知道是这样的:我怎样才能解决我的问题,因此本场比赛也不会冻结? 什么是对,而不会造成内存问题缓存地板的最佳做法是什么? 什么是去除并在屏幕上添加节点,始终引用当前地板(这是屏幕上的一个)作为最佳实践_bgLayer
?
再次,谢谢你!