首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在我的GameKit游戏中避免这些循环引用?我用的是GKAgents2D和GKBehaviours

如何在我的GameKit游戏中避免这些循环引用?我用的是GKAgents2D和GKBehaviours
EN

Stack Overflow用户
提问于 2018-04-18 12:11:48
回答 2查看 145关注 0票数 0

我使用的是GKAgents、GKGoals和GKBehaviours,但是我的行为和组件之间的内存被泄露了。我认为图像和代码可以更好地解释我的问题:

在我的实体管理器中,我返回所有无人机实体:

代码语言:javascript
复制
func droneEntities() -> [GKAgent2D] {
        for componentSystem in componentSystems {
            if componentSystem.componentClass is DroneMoveComponent.Type {
                let components = componentSystem.components

                return components.flatMap{ component in
                    return component as? GKAgent2D
                }
            }
        }
        return []
    }

我的Dronemovecomponent:

代码语言:javascript
复制
import SpriteKit
import GameplayKit

class DroneMoveComponent: GKAgent2D, GKAgentDelegate {

    weak var entityManager: EntityManager?

    init(entityManager: EntityManager) {
        self.entityManager = entityManager
        super.init()
        delegate = self
        self.maxSpeed = 50.0
        self.mass = 0.01
        self.radius = 16
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    func agentWillUpdate(_ agent: GKAgent) {
        guard let spriteComponent = entity?.component(ofType: SpriteComponent.self) else {
            return
        }

        position = vector_float2(Float(spriteComponent.node.position.x), Float(spriteComponent.node.position.y))
    }

    func agentDidUpdate(_ agent: GKAgent) {
        guard let spriteComponent = entity?.component(ofType: SpriteComponent.self) else {
            return
        }

        spriteComponent.node.position = CGPoint(x: CGFloat(position.x), y: CGFloat(position.y))
    }

    override func update(deltaTime seconds: TimeInterval) {
        super.update(deltaTime: seconds)

        if let controlledComponent = entityManager?.playerEntity?.component(ofType: ControlledComponent.self) {

            let droneEntities = entityManager?.droneEntities().filter{$0 != self}

            behavior = DroneMoveBehaviour(seek: controlledComponent, avoid: (entityManager?.berkEntities())!, drones: droneEntities!)
        }
    }
}

我的DroneMoveBehaviour:

代码语言:javascript
复制
import GameplayKit
import SpriteKit

class DroneMoveBehaviour: GKBehavior {
    init(seek: GKAgent, avoid: [GKAgent], drones: [GKAgent]) {

        super.init()
        setWeight(500, for: GKGoal(toReachTargetSpeed: 50))
        setWeight(100, for: GKGoal(toInterceptAgent: seek, maxPredictionTime: 10))
        setWeight(1000, for: GKGoal(toAvoid: avoid, maxPredictionTime: 10))
        setWeight(1000, for: GKGoal(toAvoid: drones, maxPredictionTime: 10))
    }
}

下面是我记忆图的图像:

我有另一套组件和行为以同样的方式泄漏,我想,如果有人能帮助我理解如何解决这个问题,我可以自己去纠正其他的。

数组应该包含弱引用吗?我应该转到NSPointerArray吗?还是我忽略了别的东西?如有任何指导,将不胜感激,谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-20 10:28:11

没有必要在每次更新中设置DroneMoveComponents行为!在构造函数中只移动一次这个集合似乎可以防止泄漏。

票数 0
EN

Stack Overflow用户

发布于 2021-10-30 23:40:07

面对类似的问题,在一个特定的目标上避免代理。另一种对我有效的选择是在交易/结束现场时清除代理行为。

代码语言:javascript
复制
entityManager.entities.forEach { entity in 
    entity.component(ofType: GKAgent2D.self).behavior = nil
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49899421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档