在SCNView的overlaySKScene属性中运行SpriteKit粒子系统会导致应用程序崩溃,并显示下面的堆栈跟踪.
基于堆栈跟踪,似乎所有系统代码都在运行,所以你应该如何调试崩溃,更重要的是,确定它是否是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 ()
单独查看此函数时很难分辨出发生了什么,但崩溃堆栈跟踪行SKCParticleManager :: enumerateParticleSystems(void(SKCParticleSystem *))让我怀疑该问题与粒子发射器的添加/删除有关,可能是主队列以外的队列.
SKNode docs:
Manipulations to nodes must occur in the main thread.
我将仔细检查是否仅在主队列上调用addChild和removeFromParent方法.