Ran across this runtime error while putting the finishing touches on a SpriteKit game I've been developing. Runs fine on iOS 8, but crashes on iOS 7.1 (both simulator AND device).
I've created a tiny project which recreates the issue I'm dealing with. It creates a GameScene by unarchiving an sks file created in the editor provided within Xcode 6 (just like the sample project generated when you create a new SpriteKit project). After obtaining a reference to a sprite within the generated scene using childNodeWithName:
, trying to run a simple action on it crashes the program and raises EXC_BAD_ACCESS
. Modifying the sprite's properties directly seems to work fine (see code).
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
SKSpriteNode *sprite = (SKSpriteNode*)[self childNodeWithName:@"sprite"];
// This works.
sprite.position = location;
SKAction *action = [SKAction moveByX:100 y:0 duration:1];
// This doesn't.
[sprite runAction:action];
}
}
I've been scouring the internet as well as my own brain and as far as I know, I am not breaking any rules. Please tell me that I am wrong, and specifically which rule I am breaking. Because if this turns out to be an issue that isn't my fault, the frustration would be far greater. Am I doing something that isn't available in iOS 7?
Note: The only changes I made to the generic sample SpriteKit project (the Spaceship one) is that I added a plain red sprite in the SKScene editor, gave it the name "sprite", and modified the touchesBegan:
method as shown above.
Also Note: Adding a sprite programmatically (as in the sample project) does not raise this issue, and using childNodeWithName:
to obtain a reference to it works just fine. The issue only seems to arise when accessing a sprite included in the archived sks file.
Here's the trace at the crash:
* thread #1: tid = 0x4da6c, 0x00000000, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000000
frame #1: 0x009b65d7 SpriteKit`SKCSprite::update(double) + 231
frame #2: 0x009b66de SpriteKit`SKCSprite::update(double) + 494
frame #3: 0x0099bd58 SpriteKit`-[SKNode _update:] + 43
frame #4: 0x0097c003 SpriteKit`-[SKScene _update:] + 104
frame #5: 0x009919a4 SpriteKit`-[SKView(Private) _update:] + 253
frame #6: 0x0098f5e1 SpriteKit`-[SKView renderCallback:] + 936
frame #7: 0x0098cea0 SpriteKit`__29-[SKView setUpRenderCallback]_block_invoke + 82
frame #8: 0x009b168f SpriteKit`-[SKDisplayLink _callbackForNextFrame:] + 268
frame #9: 0x009b19ad SpriteKit`-[SKDisplayLink _caDisplayLinkCallback] + 137
frame #10: 0x048cdd66 QuartzCore`CA::Display::DisplayLinkItem::dispatch() + 48
frame #11: 0x048cdc22 QuartzCore`CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 310
frame #12: 0x048ce147 QuartzCore`CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) + 123
frame #13: 0x006d4ac6 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
frame #14: 0x006d44ad CoreFoundation`__CFRunLoopDoTimer + 1181
frame #15: 0x006bc538 CoreFoundation`__CFRunLoopRun + 1816
frame #16: 0x006bb9d3 CoreFoundation`CFRunLoopRunSpecific + 467
frame #17: 0x006bb7eb CoreFoundation`CFRunLoopRunInMode + 123
frame #18: 0x02b6a5ee GraphicsServices`GSEventRunModal + 192
frame #19: 0x02b6a42b GraphicsServices`GSEventRun + 104
frame #20: 0x00aa1f9b UIKit`UIApplicationMain + 1225
* frame #21: 0x00061a2d SKTest`main(argc=1, argv=0xbff9f39c) + 141 at main.m:14
frame #22: 0x027606d9 libdyld.dylib`start + 1
[self runAction: onChildNodeWithName:];
work? - user4233369[self runAction: [SKAction runAction: onChildNodeWithName: ] ];
. Have you tried setting a break point and checking that none of the variables are nil? - user4233369