我喜欢在我的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`
由于
答案 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了解详情。