问题
The following code results to class cast exception. Could someone explain me why?
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
firstBody = contact.bodyA
secondBody = contact.bodyB
projectileDidCollide(firstBody.node as SKSpriteNode, flyingLabel: secondBody.node as SKLabelNode)
results in ClassCastException:
libswiftCore.dylib`swift_dynamicCastObjCClassUnconditional:
0x104668980: pushq %rbp
0x104668981: movq %rsp, %rbp
0x104668984: pushq %rbx
0x104668985: pushq %rax
0x104668986: movq %rsi, %rcx
0x104668989: movq %rdi, %rbx
0x10466898c: xorl %eax, %eax
0x10466898e: testq %rbx, %rbx
0x104668991: je 0x1046689ac ; swift_dynamicCastObjCClassUnconditional + 44
0x104668993: movq 0x7f236(%rip), %rsi ; "isKindOfClass:"
0x10466899a: movq %rbx, %rdi
0x10466899d: movq %rcx, %rdx
0x1046689a0: callq 0x10466b46a ; symbol stub for: objc_msgSend
0x1046689a5: testb %al, %al
0x1046689a7: movq %rbx, %rax
0x1046689aa: je 0x1046689b3 ; swift_dynamicCastObjCClassUnconditional + 51
0x1046689ac: addq $0x8, %rsp
0x1046689b0: popq %rbx
0x1046689b1: popq %rbp
0x1046689b2: retq
0x1046689b3: leaq 0xc158(%rip), %rax ; "Swift dynamic cast failed"
0x1046689ba: movq %rax, 0x87427(%rip) ; gCRAnnotations + 8
0x1046689c1: int3
0x1046689c2: nopw %cs:(%rax,%rax)
回答1:
You don't know which body is which in your contact handler — for any given contact, SpriteKit labels the two bodies bodyA
and bodyB
in arbitrary order. Even if your contact bit masks are set up so that all collisions are between a sprite and a label, bodyA
may be the sprite on one collision and the label on another.
Your contact handler should account for this. Check either possible order of bodies before handing off to code that needs to know the type of each. You can do this by conditional casting with as?
or (to be more generally useful in games with more kinds of collisions) checking the categoryBitMask
of each body.
来源:https://stackoverflow.com/questions/26316484/swift-classcastexception-when-skphysicsbody-node-sklabelnode-why