swift - 使用enumerateChildNodesWithName

时间:2015-09-08 18:39:41

标签: multithreading swift sprite-kit

我喜欢在我的spritekit游戏中使用多线程。 我使用enumerateChildNodesWithName,然后检查此对象是否与播放器发生冲突。我想在另一个线程上执行这个部分。

这是我的代码:let updateQueue: dispatch_queue_t = dispatch_queue_create("my.game", DISPATCH_QUEUE_CONCURRENT)

dispatch_async(updateQueue, { () -> Void in
            self.enumerateChildNodesWithName("lockGreen", usingBlock: { (lockGreen, stop) -> Void in
                if CGRectIntersectsRect(player.frame, lockGreen.frame) && keyGreenCollected {
                    lockGreen.removeFromParent()
                }
            })
        })

但是我收到了这个错误。我该如何解决这个问题?

*** Terminating app due to uncaught exception 'NSGenericException',   reason: '*** Collection <__NSArrayM: 0x1702407b0> was mutated while being enumerated.'
*** First throw call stack:
(0x1827c822c 0x1944940e4 0x1827c7be0 0x1870ca4bc 0x1870c9c08 0x1870c95a0 0x1000ea904 0x1000e722c 0x100954fd4 0x100954f94 0x10095e8f0 0x100954f94 0x100962b54 0x100964248 0x194cf121c 0x194cf0ee0)`
libc++abi.dylib: terminating with uncaught exception of type NSException`

由于

2 个答案:

答案 0 :(得分:2)

发生错误是因为您在循环其元素时修改集合。它与多线程无关。

使用removeFromParent从父节点中删除节点,从父节点树中删除节点。它还会从其父{q} children数组中删除该节点。发生此错误的原因是您在使用self.children循环数组元素时修改removeFromParent数组(使用enumerateChildNodesWithName)。

答案 1 :(得分:2)

我认为您的问题与多线程无关。

问题是你正在使用enumerateChildNodesWithName迭代一个集合。然后,当您仍然在迭代它时,尝试从该集合中删除元素(换句话说,在仍然枚举它的同时改变数组),这就是导致此错误的原因。

一种解决方案可能是存储应该在新数组中删除的元素,如下所示:

dispatch_async(updateQueue, { () -> Void in
        var nodesToBeRemoved = [SKNode]()
        self.enumerateChildNodesWithName("lockGreen", usingBlock: { (lockGreen, stop) -> Void in
            if CGRectIntersectsRect(player.frame, lockGreen.frame) && keyGreenCollected {
                nodesToBeRemoved.append(lockGreen)
            }
        })
    })

然后,一旦您完成迭代,也许您可​​以按照here

所述removeChildrenInArray(_ nodes: [AnyObject]!)致电SKNode

您还可以查看this question了解详情。