Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpriteKit SKEmitterNode targetNode crash EXC_BAD_ACCESS

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
like image 593
Mazyod Avatar asked Apr 06 '15 15:04

Mazyod


1 Answers

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
}
like image 105
Mazyod Avatar answered Sep 22 '22 10:09

Mazyod