This code crashes because secondBody is not associated with a node.
func didBegin(_ contact: SKPhysicsContact) {
// Set vars to hold bodies
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
// Sort bodies
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
// Handle different contacts
if firstBody.categoryBitMask == BallBitMask && secondBody.categoryBitMask == TileBitMask {
didBallTileHit(tile: secondBody.node!) // Code crashes here :(
}
...
}
1) Aside from setting a physics body to nil, what would cause a physics body to lose association with a node in SpriteKit?
2) How can a physics body even exist without a node in the first place?
An SKSPhysicsBody is an object in itself and perfectly capable of being created yet not associated with an SKSpriteNode (although perhaps not of much use :-) )
In your
didBallTileHit(), do youremoveFromParent()any of the nodes? If so, this is probably the cause of your crash in that Sprite-Kit has generated multiple collisions between 2 objects and is callingdidBegin()several times for the 2 nodes. If you then go and remove one of the nodes in the 1st call todidBegin(), it won't be there for the 2nd and subsequent calls.The way to handle it (you can't get sprite-kit to NOT call didBegin multiple times in some circumstances) is to make sure that your contact code accommodates this and that handling the contract multiple times does not cause a problem (such as adding to the score multiple times, removing multiple lives, trying to access a node or physicsBody that has been removed etc).
For more detail and possible solutions, see this answer : https://stackoverflow.com/a/44384390/1430420