如何在我的 GameKit 游戏中避免这些循环引用?我正在使用 GKAgents2D 和 GKBehaviours
How can I avoid these circular references in my GameKit game? I'm using GKAgents2D and GKBehaviours
我正在使用 GKAgents、GKGoals 和 GKBehaviours,但我的行为和组件之间出现内存泄漏。我认为图像和代码可能更好地解释我的问题:
在我的实体管理器中,我 return 所有无人机实体:
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 []
}
我的无人机移动组件:
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{[=11=] != self}
behavior = DroneMoveBehaviour(seek: controlledComponent, avoid: (entityManager?.berkEntities())!, drones: droneEntities!)
}
}
}
我的 DroneMoveBehaviour:
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 吗?还是我忽略了其他东西?非常感谢这里的任何指导,谢谢。
无需在每次更新时都设置 DroneMoveComponents 行为!在构造函数中仅移动此集合一次似乎可以防止泄漏。
在特定的避免代理目标上面临类似的问题。另一种对我有用的方法是在 deallocating/finishing 场景时清除代理行为。
entityManager.entities.forEach { entity in
entity.component(ofType: GKAgent2D.self).behavior = nil
}
我正在使用 GKAgents、GKGoals 和 GKBehaviours,但我的行为和组件之间出现内存泄漏。我认为图像和代码可能更好地解释我的问题:
在我的实体管理器中,我 return 所有无人机实体:
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 []
}
我的无人机移动组件:
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{[=11=] != self}
behavior = DroneMoveBehaviour(seek: controlledComponent, avoid: (entityManager?.berkEntities())!, drones: droneEntities!)
}
}
}
我的 DroneMoveBehaviour:
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 吗?还是我忽略了其他东西?非常感谢这里的任何指导,谢谢。
无需在每次更新时都设置 DroneMoveComponents 行为!在构造函数中仅移动此集合一次似乎可以防止泄漏。
在特定的避免代理目标上面临类似的问题。另一种对我有用的方法是在 deallocating/finishing 场景时清除代理行为。
entityManager.entities.forEach { entity in
entity.component(ofType: GKAgent2D.self).behavior = nil
}