我正在玩弄一些SpriteKit的东西。我对SpriteKit
很新,所以我的技术可能很糟糕,我不知道。这是我的工作:SpriteKit - enumerateChildNode导致崩溃“数组在枚举时发生了变异。”
它基本上是一个盾牌(2D,从上面看)的太空船。有几个“屏蔽段”(左边,右边,顶部,底部,每一个是SKShapeNode
),然后有“移相器”node
s是从边界线到设备中心的线(飞船在中央)。我想要检测相位器什么时候碰到其中一个屏蔽段。我尝试了使用collisionMasks,但它根本不起作用。所以我尝试了我自己的检测方式。
接下来,我绘制相位器的方法可能看起来很奇怪。我在网上搜索,但没有发现任何东西,真的。所以我绘制相位器的方式是通过不断更换具有稍长路径(每一帧)的phaser node
(一条直线)的路径。
这就是做这个方法,并且还导致应用崩溃:
incomingPhasers
是包含当前场景中的所有Phaser
对象的数组。 Phaser
类主要包含SKShapeNode
,称为node
和一些其他元信息。
移相器进度的提高是通过将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
导致应用崩溃时我增加许多移相器的阵列:
*终止应用程序由于未捕获的异常 'NSGenericException',原因是:“*收藏< __NSArrayM:0x17404c '
我不确定我在这里能做什么。我必须循环穿过屏蔽段节点,但是这会不断崩溃。
这是否与线程安全有关?我需要让线程安全吗?如果是这样,怎么样?
谢谢!
如果您需要更多信息或代码,请告诉我。我不能在这里发布一切,这是太多的代码。
嗯,但是什么?这些只是读取,而唯一的写入操作是'phaser.targetHit = true'。但即使我将其删除,它也会崩溃。我会尽力找出答案。编辑:即使它的主体是空的,它也会崩溃。这很奇怪 – Quantm
它必须在其他地方发生变异,可能是在不同的线程 –
嗯,还有两个地方我使用'enumerateChildNodes'。但我不会在另一个线索上打电话给他们。所有这些都是在'update(_ :)'中调用的。这不是主队列吗? – Quantm