Sprite Kit iOS 7.1在removeFromParent上崩溃
我已经更新了iPad Air 7.1和Xcode 5.1。 Xcode想要更新我的项目build议设置,我同意。
之后,当我从父节点中删除节点时,我的游戏开始在几个地方崩溃。
这对我来说是一个惊喜 – 在更新之前没有过路口。 我恢复了我的项目,发现Xcode对它做了什么 – 只改变了架构string:
之前: 更新之前的体系结构http://i57.tinypic.com/68v4nr.png
之后: 架构更新后http://i61.tinypic.com/vpeo2a.png
在旧版本中没有崩溃。 如果我删除新版本的arm64支持,没有崩溃。 在模拟器中,新旧版本都没有崩溃。
我的代码应该在哪里注意?
代码堆栈:
SpriteKit`SKCSprite::removeSubsprite(SKCSprite*): 0x1859442cc: stp fp, lr, [sp, #-16]! 0x1859442d0: add fp, sp, 0 0x1859442d4: stp x20, x19, [sp, #-16]! 0x1859442d8: sub sp, sp, #16 0x1859442dc: mov x19, x0 0x1859442e0: str x1, [sp, #8] 0x1859442e4: add x20, sp, 8 0x1859442e8: add x0, x19, 544 0x1859442ec: mov x1, x20 0x1859442f0: bl 0x18594872c ; unsigned long std::__1::__tree<SKCSprite*, std::__1::less<SKCSprite*>, std::__1::allocator<SKCSprite*> >::__erase_unique<SKCSprite*>(SKCSprite* const&) 0x1859442f4: add x0, x19, 464 0x1859442f8: mov x1, x20 0x1859442fc: bl 0x185948218 ; std::__1::list<SKCSprite*, std::__1::allocator<SKCSprite*> >::remove(SKCSprite* const&) 0x185944300: ldr x20, [sp, 1] 0x185944304: ldrb w8, [x20, #18] 0x185944308: ldrh w9, [x20, #16] 0x18594430c: orr w8, w9, w8, lsl #16 0x185944310: tbnz w8, #1, 0x185944324 ; SKCSprite::removeSubsprite(SKCSprite*) + 88 0x185944314: ldr x9, [x20, 61] 0x185944318: ldr x9, [x9, 2] 0x18594431c: cbnz x9, 0x185944324 ; SKCSprite::removeSubsprite(SKCSprite*) + 88 0x185944320: tbz w8, #8, 0x185944330 ; SKCSprite::removeSubsprite(SKCSprite*) + 100 0x185944324: mov x0, x19 0x185944328: mov x1, x20 0x18594432c: bl 0x18594828c ; SKCSprite::removeFromOffscreenList(SKCSprite*) 0x185944330: str xzr, [x20, #392] 0x185944334: ldr x8, [x20, 0] 0x185944338: ldr x8, [x8, 10] 0x18594433c: mov x0, x20 0x185944340: blr x8 0x185944344: ldrh w8, [x19, #20] 0x185944348: orr w9, w8, #0x40 0x18594434c: strh w9, [x19, #20] 0x185944350: ldr x8, [x19, 49] 0x185944354: cbz x8, 0x185944388 ; SKCSprite::removeSubsprite(SKCSprite*) + 188 0x185944358: add x9, x19, 392 0x18594435c: ldrh w10, [x8, #20] 0x185944360: orr w10, w10, #0x40 0x185944364: strh w10, [x8, #20] 0x185944368: ldr x8, [x9, 0] 0x18594436c: add x9, x8, 392 0x185944370: ldrh w10, [x8, #20] 0x185944374: orr w10, w10, #0x40 0x185944378: strh w10, [x8, #20] 0x18594437c: ldr x8, [x8, 49] 0x185944380: cbnz x8, 0x18594435c ; SKCSprite::removeSubsprite(SKCSprite*) + 144
0x185944384: ldrh w9, [x19, #20] EXC_BAD_ACCESS here.
0x185944388: orr w8, w9, #0x2 0x18594438c: strh w8, [x19, #20] 0x185944390: b 0x185944398 ; SKCSprite::removeSubsprite(SKCSprite*) + 204 0x185944394: ldrh w8, [x19, #20] 0x185944398: tbnz w8, #7, 0x1859443ac ; SKCSprite::removeSubsprite(SKCSprite*) + 224 0x18594439c: orr w8, w8, #0x80 0x1859443a0: strh w8, [x19, #20] 0x1859443a4: ldr x19, [x19, 49] 0x1859443a8: cbnz x19, 0x185944394 ; SKCSprite::removeSubsprite(SKCSprite*) + 200 0x1859443ac: sub sp, fp, #16 0x1859443b0: ldp x20, x19, [sp], #16 0x1859443b4: ldp fp, lr, [sp], #16 0x1859443b8: ret lr
更新:新信息:
我的错误:
错误http://i58.tinypic.com/30iizih.png
堆栈:
调用堆栈http://i61.tinypic.com/e6vswj.png
我发现有什么不对 我想删除的节点包含两个SKSpriteNodes(我的精灵图像及其阴影)和一个SKShapeNode(一根细的黑色绳索)。 我尝试用SKSpriteNode绳索取代我的SKShapeNode绳索,并取得成功 – 问题消失了。
从父代中删除我的节点的代码:
SKAction *moveCloud = [SKAction moveToX:destinationX duration:moveDuration]; [cloud runAction:moveCloud completion:^{ [cloud removeFromParent]; }];
代码将SKShapeNode绳索添加到我的节点:
- (void)addRopeToCloud:(SKNode *)cloud { CGFloat maxY = self.scene.size.height; CGFloat length = maxY - [self.scene convertPoint:cloud.position fromNode:cloud.parent].y; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, 0, 0); CGPathAddLineToPoint(path, NULL, 0, length); SKShapeNode *rope = [[SKShapeNode alloc] init]; rope.path = path; rope.strokeColor = [UIColor blackColor]; rope.lineWidth = 0.1; rope.antialiased = YES; rope.zPosition = -0.01; CGFloat threadScale = 1 / cloud.xScale; rope.xScale = threadScale; rope.yScale = threadScale; [cloud addChild:rope]; CGPathRelease(path); }
将SKSpriteNode绳索添加到我的节点的代码解决了问题:
- (void)addRopeToCloud:(SKNode *)cloud { CGFloat maxY = self.scene.size.height; CGFloat length = maxY - [self.scene convertPoint:cloud.position fromNode:cloud.parent].y; CGSize ropeSize = CGSizeMake(1.5, length); SKSpriteNode *rope = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:ropeSize]; rope.anchorPoint = CGPointMake(0.5, 0); CGFloat ropeScale = 1 / cloud.xScale; rope.xScale = ropeScale; rope.yScale = ropeScale; rope.zPosition = -0.01; [cloud addChild:rope]; }
在我的SKShapeNode中添加代码看起来有点不对劲,但我不明白究竟是什么。
当它的父级从iOS 7.1的超级视图中移除时,我也会碰到SKShapeNode
我的工作是将SKShapeNode属性设置为零,然后从父级移除
这似乎只发生在iOS 7.1上。 不知道这是否是一个苹果的错误,但这似乎解决了这个问题:
- (void)removeFromParent { [self.aShapeNode removeFromParent]; self.aShapeNode = nil; [super removeFromParent]; }
您可以在您释放(或呈现新场景)SKShapeNodes之前调用此方法
- (void)cleanUpChildrenAndRemove:(SKNode*)node { for (SKNode *child in node.children) { [self cleanUpChildrenAndRemove:child]; } [node removeFromParent]; }
我有同样的问题,但解决了它。 我原来的问题:
SKShapeNode有时会在dealloc EXC_BAD_ACCESS上产生崩溃
不知道如果我的情况完全模仿你的,但我得到相同的错误(具有相同的堆栈跟踪),并意识到我已经build立了两个类,每个SKShapeNode
对象保持属性。 我很确定,当我调用removeFromParent
来删除ClassA
的对象node
时,对象被释放了。 然后,在ClassB
,我调用self.node = aNewNode
(记住self.node
指向的对象已被释放),自动合成的setter尝试第二次解除node
分配。
我以为ARC应该跟踪所有这些,但是这个错误是非常零星的,所以我实在不能100%确定发生了什么。 我有一个SKSpriteNode
具有相同的模式,我从来没有见过它导致这个错误。 我现在的修复是使ClassB
属性变weak
,所以如果self.node
已经被释放,这不是问题。 希望有所帮助!
我也遇到了这个事故。 但是,覆盖removeFromParent方法并将SKShapeNode设置为零的解决scheme并不适用于我。
我发现我的崩溃是以下情况的组合:
-
有一个SKShapeNode(一个子类或一个SKNode的孩子)
-
将SKPhysicsNode附加到节点(附加到父SKNode或SKShapeNode)。
-
调用removeFromParent方法
我最终使用的解决scheme是覆盖SKShapeNode子类中的removeFromParent方法,如下所示:
- (void)removeFromParent { if( self.physicsBody != nil ) { self.physicsBody = nil; } [super removeFromParent]; }