2017-06-13 85 views
0

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

我不確定我在這裏能做什麼。我必須循環穿過屏蔽段節點,但是這會不斷崩潰。

這是否與線程安全有關?我需要讓線程安全嗎?如果是這樣,怎麼樣?

謝謝!

如果您需要更多信息或代碼,請告訴我。我不能在這裏發佈一切,這是太多的代碼。

回答

1

枚舉時不能改變(更改,添加或移除項目)。很難告訴你更多關於如何在代碼中修改更多細節的問題。有些事情是變異集合中的位置:

enumerateChildNodes(withName: "shieldSegment", using: { (node, stop) in 
    if let node = node as? ShieldSegmentNode { 
     if node.contains(phaserPoint) { 

      // collision 
      phaser.targetHit = true 

     } 
    } 
}) 

一,我解決這些問題的辦法就是我對把物品放入適合我的期望標準第二集合,然後第一枚舉後,我可以列舉在第二次收集並執行必要的突變至第一個

+0

嗯,但是什麼?這些只是讀取,而唯一的寫入操作是'phaser.targetHit = true'。但即使我將其刪除,它也會崩潰。我會盡力找出答案。編輯:即使它的主體是空的,它也會崩潰。這很奇怪 – Quantm

+0

它必須在其他地方發生變異,可能是在不同的線程 –

+0

嗯,還有兩個地方我使用'enumerateChildNodes'。但我不會在另一個線索上打電話給他們。所有這些都是在'update(_ :)'中調用的。這不是主隊列嗎? – Quantm

相關問題