我正在玩弄一些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