The Context
An SKEmitterNode
is created from an sks
file, and added as a child of some sprite. The targetNode
of the emitter is set to some other node in the scene.
func launch() {
let emitterPath = NSBundle.mainBundle().pathForResource(
"trailblaze", ofType: "sks"
)!
let emitter = NSKeyedUnarchiver.unarchiveObjectWithFile(emitterPath) as SKEmitterNode
emitter.targetNode = (sprite.scene as GameScene).canvas
sprite.addChild(emitter)
}
The Crash
The crash only happens on 64-bit devices, and here is a log:
* thread #1: tid = 0xd3127, 0x000000018a6d1194 SpriteKit`std::__1::__tree_iterator<SKCSprite*, std::__1::__tree_node<SKCSprite*, void*>*, long> std::__1::__tree<SKCSprite*, std::__1::less<SKCSprite*>, std::__1::allocator<SKCSprite*> >::find<SKCSprite*>(SKCSprite* const&) + 16, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbaddae9f5299becd)
frame #0: 0x000000018a6d1194 SpriteKit`std::__1::__tree_iterator<SKCSprite*, std::__1::__tree_node<SKCSprite*, void*>*, long> std::__1::__tree<SKCSprite*, std::__1::less<SKCSprite*>, std::__1::allocator<SKCSprite*> >::find<SKCSprite*>(SKCSprite* const&) + 16
frame #1: 0x000000018a6d1150 SpriteKit`unsigned long std::__1::__tree<SKCSprite*, std::__1::less<SKCSprite*>, std::__1::allocator<SKCSprite*> >::__erase_unique<SKCSprite*>(SKCSprite* const&) + 20
frame #2: 0x000000018a6cc900 SpriteKit`SKCSprite::removeSubsprite(SKCSprite*) + 48
frame #3: 0x000000018a6d32e4 SpriteKit`SKCEmitterSprite::~SKCEmitterSprite() + 80
frame #4: 0x000000018a6d2ef4 SpriteKit`SKCEmitterSprite::~SKCEmitterSprite() + 12
frame #5: 0x000000018a6b2068 SpriteKit`-[SKNode dealloc] + 48
frame #6: 0x0000000185f55228 CoreFoundation`CFRelease + 524
frame #7: 0x0000000185f617e8 CoreFoundation`-[__NSArrayM dealloc] + 152
frame #8: 0x000000018a6b21f4 SpriteKit`-[SKNode .cxx_destruct] + 216
frame #9: 0x0000000196a8eb1c libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 148
frame #10: 0x0000000196a9bf38 libobjc.A.dylib`objc_destructInstance + 92
frame #11: 0x0000000196a9bf90 libobjc.A.dylib`object_dispose + 28
frame #12: 0x000000018ab60d64 UIKit`-[UIResponder dealloc] + 116
frame #13: 0x000000018a6b208c SpriteKit`-[SKNode dealloc] + 84
frame #14: 0x0000000185f55228 CoreFoundation`CFRelease + 524
frame #15: 0x0000000185f617e8 CoreFoundation`-[__NSArrayM dealloc] + 152
frame #16: 0x000000018a6b21f4 SpriteKit`-[SKNode .cxx_destruct] + 216
frame #17: 0x0000000196a8eb1c libobjc.A.dylib`object_cxxDestructFromClass(objc_object*, objc_class*) + 148
frame #18: 0x0000000196a9bf38 libobjc.A.dylib`objc_destructInstance + 92
frame #19: 0x0000000196a9bf90 libobjc.A.dylib`object_dispose + 28
frame #20: 0x000000018ab60d64 UIKit`-[UIResponder dealloc] + 116
frame #21: 0x000000018a6b208c SpriteKit`-[SKNode dealloc] + 84
frame #22: 0x0000000185f55228 CoreFoundation`CFRelease + 524
frame #23: 0x0000000185f5d308 CoreFoundation`-[__NSArrayI dealloc] + 88
frame #24: 0x0000000196aa9724 libobjc.A.dylib`(anonymous namespace)::AutoreleasePoolPage::pop(void*) + 564
frame #25: 0x0000000185f58e44 CoreFoundation`_CFAutoreleasePoolPop + 28
frame #26: 0x000000018a81c844 UIKit`_wrapRunLoopWithAutoreleasePoolHandler + 76
frame #27: 0x000000018602ea50 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
frame #28: 0x000000018602b9dc CoreFoundation`__CFRunLoopDoObservers + 360
frame #29: 0x000000018602bdbc CoreFoundation`__CFRunLoopRun + 836
frame #30: 0x0000000185f590a4 CoreFoundation`CFRunLoopRunSpecific + 396
frame #31: 0x000000018f0bf5a4 GraphicsServices`GSEventRunModal + 168
frame #32: 0x000000018a88e3c0 UIKit`UIApplicationMain + 1488
* frame #33: 0x0000000100060d58 game-leader`top_level_code + 76 at AppDelegate.swift:12
frame #34: 0x0000000100060d98 game-name`main + 48 at AppDelegate.swift:0
frame #35: 0x00000001970fea08 libdyld.dylib`start + 4
The crash seems to surely be a bug originating from SpriteKit, as I have successfully fixed it by resetting the target node:
deinit {
println("Ball dealloced")
// bug on 64-bit devices
particleEmitter?.targetNode = nil
}
func launch() {
let emitterPath = NSBundle.mainBundle().pathForResource(
"trailblaze", ofType: "sks"
)!
let emitter = NSKeyedUnarchiver.unarchiveObjectWithFile(emitterPath) as SKEmitterNode
emitter.targetNode = (sprite.scene as GameScene).canvas
sprite.addChild(emitter)
particleEmitter = emitter
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With