2015-04-06 12 views
5

Der KontextSpriteKit SKEmitterNode TargetNode Absturz EXC_BAD_ACCESS

Ein SKEmitterNode aus einer sks-Datei erstellt wird, und als Kind einige Sprite hinzugefügt. Die targetNode des Senders wird auf einen anderen Knoten in der Szene gesetzt.

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

Der Absturz passiert nur auf 64-Bit-Geräte, und hier ist ein Protokoll:

* 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 

Antwort

5

Der Absturz sicher scheint von SpriteKit Ursprung um einen Fehler zu sein, wie ich es erfolgreich durch Zurücksetzen des Zielknotens behoben habe:

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 
} 
+2

Danke - hatte genau das selbe Problem und das Setzen des targetNode auf Null in der Deinit reparierte es auch für mich. Prost! – Stephen

+0

Vielen Dank !! Ich war wie verrückt, Code aus meinem Spiel zu entfernen und herauszufinden, woher diese nicht-beschreibende EXC_BAD_ACCESS stammt. Ich habe deine Lösung gefunden, ich habe alle Zeilen entfernt, in denen ich 'targetNode' verwendet habe und jetzt scheint das Spiel gut zu funktionieren. – RoberRM

+0

Noch eine Sache (nur für den Fall, dass es anderen hilft): Früher habe ich 'targetNode' verwendet, um die Partikel eines Emitters über anderen Hintergrundsinformationen erscheinen zu lassen, aber jetzt bekomme ich das gleiche Verhalten mit' .zPosition' und '. particleZPosition' Eigenschaften des Emitters (Ich setze beide Eigenschaften auf eine Zahl größer als die 'zPosition' des Hintergrundobjekts). – RoberRM