SceneKit:在SCNView上渲染SpriteKit粒子系统时应用程序崩溃,当所有代码似乎都是系统代码的一部分时如何调试

Cra*_*lot 7 particle-system scenekit sprite-kit swift

SpriteKit在a的overlaySKScene属性中运行粒子系统SCNView会导致应用程序与下面的堆栈跟踪一起崩溃.

基于堆栈跟踪,似乎所有系统代码都在运行,所以你应该如何调试崩溃,更重要的是,确定它是否是SceneKit/SpriteKit的错误或应用程序中的错误?

对于它的价值,下面是添加粒子系统的函数,但它没有在堆栈跟踪中引用.

fileprivate func animateFireworks(scnPoint: CGPoint, color: UIColor) {
    // Set emitter properties
    let particleBirthRate = CGFloat(150)
    let maxParticles = 50
    let numEmitters = 5

    // SceneView point -> SpriteKit point
    let skOverlayPoint = skOverlay.convertPoint(fromView: scnPoint)

    // Create emitters
    for _ in 0..<numEmitters {
        let fireworksEmitter = SKEmitterNode(fileNamed: ExplosionEmitterFilename)!

        // Set particle size
        let particleSize = CGSize(width: 20, height: 20)
        fireworksEmitter.particleSize = particleSize

        // Set color for emitter
        fireworksEmitter.particleColorSequence = nil
        fireworksEmitter.particleColor = color

        // Set number of particles
        fireworksEmitter.particleBirthRate = particleBirthRate
        fireworksEmitter.numParticlesToEmit = maxParticles

        // Position at point
        fireworksEmitter.position = skOverlayPoint

        // Add to SpriteKit overlay
        skOverlay.addChild(fireworksEmitter)

        // Remove emitter, <animationDur> is only a rough estimate
        let animationDur = 3 * Double(fireworksEmitter.particleLifetime + fireworksEmitter.particleLifetimeRange)
        delay(animationDur) {
            fireworksEmitter.removeFromParent()
        }
    }
}


func delay(_ delay:Double, closure:@escaping ()->()) {
    DispatchQueue.main.asyncAfter(
        deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}


> Thread 11 Queue : com.apple.scenekit.renderingQueue.SCNView0x121d8d570
> (serial)
> #0    0x000000019c710aac in SKCParticleManager::enumerateParticleSystems(void (SKCParticleSystem*)
> block_pointer) ()
> #1    0x000000019c723d74 in SKCParticleSystemNode::generateRenderData_Quads(SKCRenderInfo*) ()
> #2    0x000000019c7236c0 in SKCParticleSystemNode::addRenderOps_Quads(SKCRenderInfo*,
> std::__1::shared_ptr<jet_command_buffer> const&) ()
> #3    0x000000019c71dc4c in SKCRenderer::expandRenderGroup(std::__1::shared_ptr<SKCRenderSortGroup>
> const&, std::__1::shared_ptr<jet_command_buffer> const&) ()
> #4    0x000000019c71b238 in SKCRenderer::expandRenderPass(std::__1::shared_ptr<SKCRenderPass>
> const&, std::__1::shared_ptr<jet_command_buffer> const&) ()
> #5    0x000000019c71a888 in SKCRenderer::render(SKCNode*, float __vector(4), std::__1::shared_ptr<jet_framebuffer> const&, unsigned int __vector(4), simd_float4x4, bool, NSDictionary*, SKCStats*,
> SKCStats*, double) ()
> #6    0x000000019c6516a4 in -[SKSCNRenderer renderWithEncoder:pass:commandQueue:] ()
> #7    0x0000000199479fc8 in -[SCNRenderContextMetal renderSKSceneWithRenderer:overlay:atTime:] ()
> #8    0x0000000199525018 in -[SCNRenderer _drawOverlaySceneAtTime:] ()
> #9    0x00000001995e199c in __C3DEngineContextRenderPassInstance ()
> #10   0x00000001995e27cc in C3DEngineContextRenderMainTechnique ()
> #11   0x0000000199526508 in -[SCNRenderer _renderSceneWithEngineContext:sceneTime:] ()
> #12   0x0000000199526688 in -[SCNRenderer _drawSceneWithNewRenderer:] ()
> #13   0x0000000199526ccc in -[SCNRenderer _drawScene:] ()
> #14   0x0000000199527144 in -[SCNRenderer _drawAtTime:] ()
> #15   0x00000001995cfa74 in -[SCNView _drawAtTime:] ()
> #16   0x00000001994876c0 in __69-[NSObject(SCN_DisplayLinkExtensions) SCN_setupDisplayLinkWithQueue:]_block_invoke ()
> #17   0x000000019959700c in __36-[SCNDisplayLink _callbackWithTime:]_block_invoke ()
> #18   0x00000001042a12cc in _dispatch_call_block_and_release ()
> #19   0x00000001042a128c in _dispatch_client_callout ()
> #20   0x00000001042aff80 in _dispatch_queue_serial_drain ()
> #21   0x00000001042a47ec in _dispatch_queue_invoke ()
> #22   0x00000001042b0f6c in _dispatch_root_queue_drain_deferred_wlh ()
> #23   0x00000001042b8020 in _dispatch_workloop_worker_thread ()
> #24   0x00000001858a6f1c in _pthread_wqthread ()
Run Code Online (Sandbox Code Playgroud)

Rob*_*ern 3

单独查看此函数时,很难判断发生了什么,但崩溃堆栈跟踪线SKCParticleManager::enumerateParticleSystems(void (SKCParticleSystem*)让我怀疑该问题与粒子发射器的添加/删除有关,可能在主队列以外的队列上。

SKNode 文档

对节点的操作必须发生在主线程中。

我会仔细检查addChildremoveFromParent方法是否仅在主队列上被调用。