我正在玩弄一些 SpriteKit 的东西。我是 SpriteKit
的新手,所以我的技术可能不好,我不知道。这是我正在做的事情:
它基本上是一艘带护盾的宇宙飞船(2D,从上方看)。有几个“屏蔽段”(左、右、上、下,每个都是一个 SKShapeNode
),然后是“移相器”节点
,它们是从中绘制的线设备中心的边界(宇宙飞船在中心)。我想检测相位器何时击中其中一个护盾部分。我使用 collisionMasks 尝试了这个,但它根本不起作用。所以我尝试了自己的检测方式。
接下来,我绘制移相器的方法可能看起来很奇怪。我在网上搜索但没有找到任何东西,真的。因此,我绘制移相器的方法是不断用每帧稍长的路径替换 移相器节点
(一条直线)的路径。
这是执行此操作并导致应用程序崩溃的方法:
incomingPhasers
是一个包含当前场景中所有 Phaser
对象的数组。 Phaser
类主要包含名为node
的SKShapeNode
和其他一些元信息。
phaser progress 的推进是通过将 progress
属性增加一点来完成的。 delta 是自上一帧以来的时间差(因为此方法是从 update(_:)
let vector
是用于画线的位移矢量。
private func advancePhasers(_ delta: TimeInterval) {
for phaser in incomingPhasers where !phaser.targetHit {
// advance progress of phaser
phaser.progress = min(phaser.progress + CGFloat(delta) * phaser.progressRate, 1)
let vector = phaser.origin.vector(toPoint: phaser.target, fraction: phaser.progress)
// create new path
let path = UIBezierPath()
path.move(to: phaser.origin)
path.addLine(to: phaser.origin + vector)
phaser.node.path = path.cgPath
// check collision
let phaserPoint = path.currentPoint
enumerateChildNodes(withName: "shieldSegment", using: { (node, stop) in
if let node = node as? ShieldSegmentNode {
if node.contains(phaserPoint) {
// collision
phaser.targetHit = true
}
}
})
}
}
enumerateChildNodes
当我向数组添加许多移相器时导致应用程序崩溃:
* Terminating app due to uncaught exception 'NSGenericException', reason: '* Collection <__NSArrayM: 0x17404ce40> was mutated while being enumerated.'
我不确定我能在这里做什么。我必须循环遍历屏蔽段节点,但这一直在崩溃。
这跟线程安全有关系吗?我需要让它线程安全吗?如果是,怎么办?
谢谢!
如果您需要更多信息或代码,请告诉我。我不能在这里发布所有内容,代码太多了。
最佳答案
在枚举集合时,您不能更改(更改、添加或删除项目)集合。如果没有代码中的更多详细信息,很难告诉您更多有关如何修复它的信息。有些东西正在改变这里的集合:
enumerateChildNodes(withName: "shieldSegment", using: { (node, stop) in
if let node = node as? ShieldSegmentNode {
if node.contains(phaserPoint) {
// collision
phaser.targetHit = true
}
}
})
我解决这些问题的一种方法是我有第二个集合,用于将项目放入符合我所需标准的项目,然后在第一次枚举之后,我可以枚举第二个集合并对第一个集合执行必要的突变
关于ios - SpriteKit - enumerateChildNode 导致崩溃 "array was mutated while being enumerated.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44531725/