Even when the action is run on the main thread, the following code causes a crash on iOS, but not on macOS. The game launches with a simple yellow rectangle, and when it finishes fading out and should be removed from the overlay scene, the app crashes.
The code can be pasted into the file GameController.swift of Xcode's default project for Multiplatform macOS and iOS game.
import SceneKit import SpriteKit @MainActor class GameController: NSObject { let scene: SCNScene let sceneRenderer: SCNSceneRenderer init(sceneRenderer renderer: SCNSceneRenderer) { sceneRenderer = renderer scene = SCNScene(named: "Art.scnassets/ship.scn")! super.init() sceneRenderer.scene = scene renderer.overlaySKScene = SKScene(size: CGSize(width: 500, height: 500)) DispatchQueue.main.async { let node = SKShapeNode(rect: CGRect(x: 100, y: 100, width: 100, height: 100)) node.fillColor = .yellow node.run(.sequence([ .fadeOut(withDuration: 1), .removeFromParent() ])) renderer.overlaySKScene!.addChild(node) } } }
The Xcode console shows this stacktrace:
*** Assertion failure in -[UIApplication _performAfterCATransactionCommitsWithLegacyRunloopObserverBasedTiming:block:], UIApplication.m:3246 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Call must be made on main thread' *** First throw call stack: ( 0 CoreFoundation 0x00000001804ae0f8 __exceptionPreprocess + 172 1 libobjc.A.dylib 0x0000000180087db4 objc_exception_throw + 56 2 Foundation 0x0000000180d17058 _userInfoForFileAndLine + 0 3 UIKitCore 0x00000001853cf678 -[UIApplication _performAfterCATransactionCommitsWithLegacyRunloopObserverBasedTiming:block:] + 376 4 UIKitCore 0x000000018553f7a0 -[_UIFocusUpdateThrottle scheduleProgrammaticFocusUpdate] + 300 5 UIKitCore 0x0000000184e2e22c -[UIFocusSystem _requestFocusUpdate:] + 548 6 UIKitCore 0x0000000184e2dfa4 -[UIFocusSystem requestFocusUpdateToEnvironment:] + 76 7 UIKitCore 0x0000000184e2e864 -[UIFocusSystem _focusEnvironmentWillDisappear:] + 408 8 SpriteKit 0x00000001a3d472f4 _ZL12_removeChildP6SKNodeS0_P7SKScene + 240 9 SpriteKit 0x00000001a3d473b0 -[SKNode removeChild:] + 80 10 SpriteKit 0x00000001a3d466b8 -[SKNode removeFromParent] + 128 11 SpriteKit 0x00000001a3d1678c -[SKRemove updateWithTarget:forTime:] + 64 12 SpriteKit 0x00000001a3d1b740 _ZN11SKCSequence27cpp_updateWithTargetForTimeEP7SKCNoded + 84 13 SpriteKit 0x00000001a3d20e3c _ZN7SKCNode6updateEdf + 156 14 SpriteKit 0x00000001a3d20f20 _ZN7SKCNode6updateEdf + 384 15 SpriteKit 0x00000001a3d26fb8 -[SKScene _update:] + 464 16 SpriteKit 0x00000001a3cf3168 -[SKSCNRenderer _update:] + 80 17 SceneKit 0x000000019c932bf0 -[SCNMTLRenderContext renderSKSceneWithRenderer:overlay:atTime:] + 60 18 SceneKit 0x000000019c9ebd98 -[SCNRenderer _drawOverlaySceneAtTime:] + 204 19 SceneKit 0x000000019cb1a1c0 _ZN3C3D11OverlayPass7executeERKNS_10RenderArgsE + 60 20 SceneKit 0x000000019c8e05ec _ZN3C3D13__renderSliceEPNS_11RenderGraphEPNS_10RenderPassERtRKNS0_9GraphNodeERPNS0_5StageENS_10RenderArgsEbRPU27objcproto16MTLCommandBuffer11objc_object + 2660 21 SceneKit 0x000000019c8e18ac _ZN3C3D11RenderGraph7executeEv + 3808 22 SceneKit 0x000000019c9ed26c -[SCNRenderer _renderSceneWithEngineContext:sceneTime:] + 756 23 SceneKit 0x000000019c9ed544 -[SCNRenderer _drawSceneWithNewRenderer:] + 208 24 SceneKit 0x000000019c9ed9fc -[SCNRenderer _drawScene:] + 40 25 SceneKit 0x000000019c9edce4 -[SCNRenderer _drawAtTime:] + 500 26 SceneKit 0x000000019ca87950 -[SCNView _drawAtTime:] + 368 27 SceneKit 0x000000019c943b74 __83-[NSObject(SCN_DisplayLinkExtensions) SCN_setupDisplayLinkWithQueue:screen:policy:]_block_invoke + 44 28 SceneKit 0x000000019ca50600 -[SCNDisplayLink _displayLinkCallbackReturningImmediately] + 132 29 libdispatch.dylib 0x000000010239173c _dispatch_client_callout + 16 30 libdispatch.dylib 0x0000000102394c14 _dispatch_continuation_pop + 756 31 libdispatch.dylib 0x00000001023aa4e0 _dispatch_source_invoke + 1736 32 libdispatch.dylib 0x00000001023997f0 _dispatch_lane_serial_drain + 340 33 libdispatch.dylib 0x000000010239a774 _dispatch_lane_invoke + 420 34 libdispatch.dylib 0x00000001023a71a8 _dispatch_root_queue_drain_deferred_wlh + 324 35 libdispatch.dylib 0x00000001023a6604 _dispatch_workloop_worker_thread + 488 36 libsystem_pthread.dylib 0x000000010242bb74 _pthread_wqthread + 284 37 libsystem_pthread.dylib 0x000000010242a934 start_wqthread + 8 ) libc++abi: terminating due to uncaught exception of type NSException
Am I doing something wrong?
Yes, it does crash on the iPad simulator. It didn't crash for me on the iPhone simulator. Try this:
let node = SKShapeNode(rect: CGRect(x: 100, y: 100, width: 100, height: 100)) node.fillColor = .yellow let removeAction = SKAction.run { DispatchQueue.main.async { node.removeFromParent() } } node.run(.sequence([ .fadeOut(withDuration: 5), removeAction])) renderer.overlaySKScene!.addChild(node)