0

I'm writing a game using SpriteKit and GameplayKit, where a lot of entities use pathfinding logics to move around. Therefore I want run the pathfinding code in the background. However, I occasionally get a EXC_BAD_ACCESS error from either of these line:

    scene.obstacleGraph.connectUsingObstacles(node: startNode)
    scene.obstacleGraph.connectUsingObstacles(node: endNode)

Here is the code for my pathfinding logic:

func findPathToTarget(targetLocation: CGPoint) {
    DispatchQueue.global(qos: .background).async {
     
        unowned let scene = enemyEntity.spriteComponent.node.scene as! WorldScene
        
        let startNode = GKGraphNode2D(point: vector_float2(Float(enemyEntity.spriteComponent.node.position.x), Float(enemyEntity.spriteComponent.node.position.y)))
        let endNode = GKGraphNode2D(point: vector_float2(Float(targetLocation.x), Float(targetLocation.y)))

            scene.obstacleGraph.connectUsingObstacles(node: startNode)
            scene.obstacleGraph.connectUsingObstacles(node: endNode)

        let pathNodes = scene.obstacleGraph.findPath(from: startNode, to: endNode) as! [GKGraphNode2D]
        
        DispatchQueue.main.async {
            scene.obstacleGraph.remove([startNode, endNode])
        }
        
        guard  pathNodes.count > 1 else { return }

        let attackPath = GKPath(graphNodes: pathNodes, radius: 16.0)
        
        enemyEntity.agent!.behavior = GKAgentBehaviors.followPath(forAgent: enemyEntity.agent!, speed: enemyEntity.stats[.movementSpeed]!, onPath: attackPath)
    }
}

I'm not experienced at working with GCD, therefore I'd like to have a better understanding of it. Can someone please tell me what I'm doing wrong with the DispatchQueue in the my code.

Thank you for any help.

Bob
  • 155
  • 1
  • 8
  • 1
    I suspect the use of `unowned`. Have a look at [What is the difference between a weak reference and an unowned reference?](https://stackoverflow.com/questions/24011575/what-is-the-difference-between-a-weak-reference-and-an-unowned-reference) along with many others that compare `unowned` and `weak` (and `strong`). – HangarRash Sep 01 '23 at 23:22
  • Thanks for the insight. However if the use of unowned was the issue should the app crash every time instead of only occasionally? – Bob Sep 01 '23 at 23:49
  • 1
    It would only crash if the unowned scene happens to get deallocated while this block of code happens to be running. – HangarRash Sep 01 '23 at 23:54
  • the scene will never be nil or get deallocated during the game is running though. As it is the game scene where all the moving entities are running around in. – Bob Sep 01 '23 at 23:57
  • "I'm not experienced at working with GCD, therefore I'd like to have a better understanding of it" You might be better off learning async/await instead. – matt Sep 02 '23 at 00:36
  • Thanks for the advised and I looked into async/await. unless I'm wrong it requires a return type to work.However my function does not return anything. how do I implement it? – Bob Sep 02 '23 at 02:11
  • Swift concurrency does not require functions to return a value. – Rob Sep 02 '23 at 05:23
  • thanks the advice. However it still crashes occasionally after having changed unowned to weak pattern. Guess that's not where the issue lies. – Bob Sep 02 '23 at 15:20
  • Then, either edit this question showing us your latest rendition (without `unowned` and without `!` force unwrapping operators) or delete this question entirely and post another. Ideally, if you can reduce this down to a [MRE](https://stackoverflow.com/help/minimal-reproducible-example), that would be best. It’s hard to help you if we cannot reproduce the problem. – Rob Sep 02 '23 at 15:50

0 Answers0