My incredibly short app code somehow generates an EXC_BAD_ACCESS error. I have reproduced the error on a completely fresh app. But I can not comprehend how this happens.
Here is the entire code for my app (aside from what xcode generates automatically for a spritekit game).
-(void)didMoveToView:(SKView *)view {
SKNode* pFirst = [SKNode node];
[self addChild:pFirst];
//
SKSpriteNode* pSprite = [SKSpriteNode spriteNodeWithImageNamed:@"img61.png"];
pSprite.centerRect = CGRectMake(0.4,0.4, 0.2, 0.2); // suspect 1
pSprite.position = CGPointMake(0,0);
pSprite.xScale = 2.0;
pFirst.alpha = 0.0; // suspect 2
//
[pFirst addChild:pSprite];
}
The debugger places the crash point here:
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
How can I understand what is wrong here?
Of course, this problem originally comes from a much longer app that was crashing. This is what code I had left when I simplified it, but preserved the crash.
Two lines are marked as "suspects". Amazingly, the code runs fine if EITHER suspect1 or suspect2 are removed. I can not comprehend this at all.
We may find some hint from the description of centerRect
,
A property that defines how the texture is applied to the sprite.
So if you set centerRect
of a sprite along with setting its alpha = 0.0
, the alpha blended into the framebuffer will be 0 (See Creating a Textured Sprite for more information). From the current case we just tested, the zero-alpha sprite is treated as a null sprite. So adding a child node to the null sprite will cause crash.
To solve the problem, one method is to change pFirst.alpha = 0.0;
to pFirst.hidden = YES;
. An alternative is to set the alpha after a sprite rendered to the scene. In your didMoveToView method, assign an identifier for pFirst
,
pFirst.name = @"firstNode"
Then, add the following method to set alpha to zero after physics simulations are performed,
- (void)didSimulatePhysics
{
[self enumerateChildNodesWithName:@"firstNode" usingBlock:^(SKNode *node, BOOL *stop) {
if (node.alpha > 0.0) {
node.alpha = 0.0;
}
}];
}