gpt4 book ai didi

ios - 当一个对象的属性同时被另外两个对象设置时,CPU 会达到 %100

转载 作者:行者123 更新时间:2023-11-29 05:40:50 24 4
gpt4 key购买 nike

我正在处理一个特别令人讨厌的错误,它会导致主线程达到 %100 并且 UI 完全卡住。

本质上,这是一个“模拟”,其中 100 个节点实例被创建为“单元”,另外 2 个节点被创建为攻击者和防御者。这些细胞有两种属性,成瘾和烦恼,攻击者和防御者每秒都会修改它们。

我运行一个计时器,对每个攻击者和防御者调用 fire() 方法,并传递随机选择的单元格作为参数。

攻击者中的fire()方法将根据时间T(即自模拟启动以来耗时)计算自己的功率,并在传递的单元上调用increaseAddiction()和increaseAnnoyance()方法,将其计算出来力量。防御者单元的 fire() 方法也会发生同样的事情,但这次调用 decreaeAddiction() 和 reduceAnnoyance() 方法。

力量计算不是线性函数,并且对于攻击者和防御者来说,创造统治时刻的攻击者和防御者是不同的。细胞节点根据其成瘾和烦恼程度进行着色,使其成为有趣的动画。

在模拟开始运行一段时间 T 后,问题出现。我能够挑出“self.annoyanceLevel = newLevel”行作为罪魁祸首,删除后代码不会显示此行为。此外,当从攻击者或防御者身上删除 fire() 方法时,问题不会发生,这导致我怀疑存在竞争条件,因此我尝试依次调用这些方法,而不是同时调用它们,但这没有帮助。我尝试创建一个新的调度队列并从那里调用它们,但没有帮助。我尝试通过将单元格标记为“inUse”来创建锁定/解锁机制,直到 setAnnoyance() 返回,但这没有帮助,我尝试通过将更改添加到数组并单独调用 setAnnoyanceLevels() 来使用来查询更改que 数组中的值,但没有帮助。我找不到任何除以零之类的东西,或者其他逻辑问题,例如意外的无限循环。

我尝试对导致问题的值进行硬编码(显然当它从 63 更改为 100 时会挂起),这解决了问题,但是,这对我没有帮助,因为我不需要硬编码的数字。

这是函数的简化版本

Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(fireAtCells), userInfo: nil, repeats: true)


/* The methods that run the simulation */
@objc func fireAtCells(){

for bot in GameEngine().data.attackBots{

var targetCells = GameEngine().data.cells.filter { cell in
return cell.addictionLevel < 100
}


let pickedCell = Int.random(in: 0 ... targetCells.count - 1)


bot.fire(cell: targetCells[pickedCell])
}
}
for bot in GameEngine().data.defenceBots{

var targetCells = GameEngine().data.cells.filter { cell in
return cell.addictionLevel > 0 || cell.annoyanceLevel > 0
}


let pickedCell = Int.random(in: 0 ... targetCells.count - 1)


bot.fire(cell: targetCells[pickedCell])
}
}


}

/* These are the methods on the attacker and defender that calculate the power etc. and increaseAddicton or decreaseAnnoyance, decreaseAddiction methods on the Cells */

func fire(cell: Cell){

let gameStatus = GameEngine()

let pickBullet = Int.random(in: 0 ... bullets.count - 1)
let bullet = bullets[pickBullet]

switch bullet {
case .addict:
cell.decreaseAnnoyance(50)
cell.increaseAddiction(Int(gameStatus.status.attackPower))
bulletColor = .red
case .annoy:
let power = Int(gameStatus.status.attackPower)
cell.increaseAnnoyance(power)

}


}

/* The methods in the Cell objects that adjust it's own properties when called from the attacker or defender, addiction methods are pretty much the same, so ommiting them */

func increaseAnnoyance(_ power: Int){
self.setAnnoyanceLevel(power + self.annoyanceLevel)
}
func decreaseAnnoyance(_ power: Int){
self.setAnnoyanceLevel(self.annoyanceLevel - power)
}



func setAnnoyanceLevel(_ level : Int){

let newLevel = (level > 100) ? 100 : (level < 1 ? 1 : level)

self.annoyanceLevel = newLevel


self.wiggle(interval: 0.5 - 0.004 * Double(level), strength: 20)
self.colorize(color: UIColor.yellow, level: level)

}

enter image description here

enter image description here

enter image description here

更新:我能够在 CPU 达到 %100 之前拦截执行,看起来计时器行为不正常。在increaseAnnoyance()返回并且计时器准备触发FireAtCells()方法之后,它不知何故陷入了无限循环。在 %100 问题之前的最后一个循环中,我可以看到 Timer 对象从未真正完成初始化,也没有调用 ForeAtCells 方法,而是卡住了。

更新 2 好吧,奇怪的是,计时器上次从未完成执行,但 %100 CPU 似乎是由 Spritekit 节点上的某些 SKAction 使用的计时器引起的。 SpriteKit Actions 从不访问这些属性,我不明白为什么只有在以编程方式更改对象属性时才会导致问题。

最佳答案

尝试一下,如果消除了双循环,并删除了计时器:

let action = SKAction.repeatForever(SKAction.sequence([SKAction.run{fireAtCells()},SKAction.wait(forDuration:0.2)]))
scene.run(action)


/* The methods that run the simulation */
@objc func fireAtCells(){
var attackTargetCells = GameEngine().data.cells.filter { cell in
return cell.addictionLevel < 100
}
for bot in GameEngine().data.attackBots{
let pickedCell = attackTargetCells[Int.random(in: 0 ... attackTargetCells.count - 1)]
bot.fire(cell: pickedCell)
if pickedCell.addictionLevel >= 100 {
attackTargetCells.remove(pickedCell)
}
}
let defenceTargetCells = GameEngine().data.cells.filter { cell in
return cell.addictionLevel > 0 || cell.annoyanceLevel > 0
}
for bot in GameEngine().data.defenceBots{
let pickedCell = defenseTargetCells[Int.random(in: 0 ... defenseTargetCells.count - 1)]
bot.fire(cell: pickedCell)
if cell.addictionLevel <= 0 || cell.annoyanceLevel <= 0 {
defenseTargetCells.remove(pickedCell)
}
}
}

/* These are the methods on the attacker and defender that calculate the power etc. and increaseAddicton or decreaseAnnoyance, decreaseAddiction methods on the Cells */

func fire(cell: Cell){
let gameStatus = GameEngine()
let pickBullet = Int.random(in: 0 ... bullets.count - 1)
let bullet = bullets[pickBullet]
switch bullet {
case .addict:
cell.decreaseAnnoyance(50)
cell.increaseAddiction(Int(gameStatus.status.attackPower))
bulletColor = .red
case .annoy:
let power = Int(gameStatus.status.attackPower)
cell.increaseAnnoyance(power)

}
}

/* The methods in the Cell objects that adjust it's own properties when called from the attacker or defender, addiction methods are pretty much the same, so ommiting them */

func increaseAnnoyance(_ power: Int){
self.setAnnoyanceLevel(power + self.annoyanceLevel)
}
func decreaseAnnoyance(_ power: Int){
self.setAnnoyanceLevel(self.annoyanceLevel - power)
}



func setAnnoyanceLevel(_ level : Int){
let newLevel = (level > 100) ? 100 : (level < 1 ? 1 : level)
self.annoyanceLevel = newLevel
self.wiggle(interval: 0.5 - 0.004 * Double(level), strength: 20)
self.colorize(color: UIColor.yellow, level: level)
}

关于ios - 当一个对象的属性同时被另外两个对象设置时,CPU 会达到 %100,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56575151/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com