2017-06-13 57 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