阅读有关此错误的所有帖子与内存相关并尝试访问不再存在的内容。
问题:错误几乎随机出现。它可以在第一个敌人被杀或第N个敌人被杀后出现。但是,只有当敌人被杀时才会出现。
测试:在iPhone 5上运行iOS 8 beta 5,Xcode 6 beta 5。
代码流程
Enemy SKNodes类实例在级别开始时创建并存储在NSMutableArray中以供参考:
Goblin *newGoblin = [[Goblin alloc] initFacingDirection:1];
// set various properties…
[enemyGoblins addObject:newGoblin];
玩家的剑与敌人接触:
NSMutableArray *discardedItems = [NSMutableArray array];
for(Goblin *object in enemyGoblins)
{
[object runBloodBurst:true damagePoints:_player.swordDamage];
if(object.goblinHealth < 0)
[discardedItems addObject:object];
}
if([discardedItems count] > 0)
[enemyGoblins removeObjectsInArray:discardedItems];
在Goblin类中,“die”代码是:
if(self.goblinHealth < 0)
{
SKAction *wait0 = [SKAction waitForDuration:1.0];
SKAction *block0 = [SKAction runBlock:^{
[self removeActionForKey:@"animation"];
[self runAction:[_animations goblin_dieLeft]];
}];
SKAction *block1 = [SKAction runBlock:^{
[self removeFromParent];
}];
[self runAction:[SKAction sequence:@[block0, wait0, block1]]];
}
我尝试了什么: 我禁用了“abandonedItems”代码,因为我认为一旦引用丢失,ARC可能会从内存中转储对象,随后的Goblin类“死亡动画”会导致崩溃,但这并没有解决问题。 我尝试了僵尸和断点,但也没有找到有用的线索。
关于我尝试过的内容,或者有人在Beta 5中遇到过类似的问题,我是否咆哮错误的树?
修改
这是回溯:
(lldb)bt * thread#1:tid = 0x3264b,0x000000018cb13434 SpriteKit
SKCSprite::update(double) + 404, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x7000000000000018) frame #0: 0x000000018cb13434 SpriteKit
SKCSprite :: update(double)+ 404 帧#1:0x000000018cb13440 SpriteKitSKCSprite::update(double) + 416 frame #2: 0x000000018cb13440 SpriteKit
SKCSprite :: update(double)+ 416 帧#3:0x000000018cacbf28 SpriteKit-[SKScene _update:] + 140 frame #4: 0x000000018cae63f8 SpriteKit
- [SKView(私有)_update:] + 568 帧#5:0x000000018cae3a10 SpriteKit-[SKView renderCallback:] + 764 frame #6: 0x000000018cae0a9c SpriteKit
__ 29- [SKView setUpRenderCallback] _block_invoke + 60 帧#7:0x000000018cb0d890 SpriteKit-[SKDisplayLink _callbackForNextFrame:] + 272 frame #8: 0x000000010042ca9c libglInterpose.dylib
- [DYDisplayLinkInterposer forwardDisplayLinkCallback:] + 168 frame#9:0x000000018c615b90 QuartzCoreCA::Display::DisplayLinkItem::dispatch() + 32 frame #10: 0x000000018c615a28 QuartzCore
CA :: Display :: DisplayLink :: dispatch_items(unsigned long long,unsigned long long,unsigned long long)+ 324 帧#11:0x00000001897dddc0 IOKitIODispatchCalloutFromCFMessage + 376 frame #12: 0x00000001885dcf34 CoreFoundation
__ CFMachPortPerform + 180 帧#13:0x00000001885f1b38 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56 frame #14: 0x00000001885f1a98 CoreFoundation
__ CFRunLoopDoSource1 + 436 帧#15:0x00000001885efa18 CoreFoundation__CFRunLoopRun + 1640 frame #16: 0x000000018851d664 CoreFoundation
CFRunLoopRunSpecific + 396 帧#17:0x000000019154f5a4 GraphicsServicesGSEventRunModal + 168 frame #18: 0x000000018ccd6164 UIKit
UIApplicationMain + 1488 *帧#19:0x0000000100165530 CarcerQuestmain(argc=1, argv=0x000000016fdab9d8) + 116 at main.m:16 frame #20: 0x000000019885aa08 libdyld.dylib
开始+4 (lldb)
答案 0 :(得分:3)
更改
[self runAction:[SKAction sequence:@[block0, wait0, block1]]];
到
[self runAction:[SKAction sequence:@[block0, wait0]] completion:^{
[_self removeFromParent];
}];
在更新IOS7代码以在IOS8上运行时,我遇到了同样的问题,并使用完成块修复了问题。
答案 1 :(得分:2)
阅读您的问题的评论,我不确定您是否已解决此问题,并且您的代码段不够完整,我无法看到您的问题,但我最近遇到了类似的问题,它我花了一段时间才弄明白,所以我发布它,以防它对你或未来的帖子读者有所帮助。
您可以在此处查看我的代码更改:https://github.com/ik/2048/commit/3ffec547367320c7e179624a14ac5867ed1acea2
基本上发生的事情runAction
是异步的。它在下一个屏幕刷新周期中执行(因此在堆栈跟踪中显示链接调用)。因此,如果您在removeSomething
之后致电runAction
,则可以在操作开始之前执行,并且您将崩溃。
至少那是抓住我的 - 我不知道为什么它在iOS 7中从未发生过。请参阅下面的代码。
- [self removeFromParentCell]; // Used to call it here - wrong.
SKAction *wait = [SKAction waitForDuration:GSTATE.animationDuration];
SKAction *remove = [SKAction removeFromParent];
- [self runAction:[SKAction sequence:@[wait, remove]]];
+ [self runAction:[SKAction sequence:@[wait, remove]] completion:^{
+ [self removeFromParentCell]; // This is right.
+ }];
答案 2 :(得分:0)
在搜索Apple支持论坛并在iOS 7上运行相同的项目之后,看起来这是一个Beta发布错误,而不是错误的代码。