Multithreading swift-使用EnumerateChildNodeWithName发生多线程错误
我喜欢在我的spritekit游戏中使用多线程。 我使用enumerateChildNodesWithName,然后检查这个对象是否与播放器发生了碰撞。我想在另一个线程上执行这个部分 这是我的代码:Multithreading swift-使用EnumerateChildNodeWithName发生多线程错误,multithreading,swift,sprite-kit,Multithreading,Swift,Sprite Kit,我喜欢在我的spritekit游戏中使用多线程。 我使用enumerateChildNodesWithName,然后检查这个对象是否与播放器发生了碰撞。我想在另一个线程上执行这个部分 这是我的代码:let updateQueue:dispatch\u queue\u t=dispatch\u queue\u create(“my.game”,dispatch\u queue\u CONCURRENT) 但我得到了这个错误。我怎样才能解决这个问题 *** Terminating app due t
let updateQueue:dispatch\u queue\u t=dispatch\u queue\u create(“my.game”,dispatch\u queue\u CONCURRENT)
但我得到了这个错误。我怎样才能解决这个问题
*** 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`
***由于未捕获的异常“NSGenericeException”而终止应用程序,原因:“***集合在枚举时发生了变异。”
***第一次抛出调用堆栈:
(0x1827c822c 0x1944940e4 0x1827c7be0 0x1870ca4bc 0x1870c9c08 0x1870c95a0 0x1000ea904 0x1000e722c 0x100954fd4 0x100954f94 0x10095e8f0 0x100954f94 0x100962b54 0x100964248 0x194cf121c 0x194cf0ee0)`
libc++abi.dylib:以NSException类型的未捕获异常终止`
谢谢,发生此错误是因为您在对集合的元素进行循环时正在修改集合。它与多线程无关
使用
removeFromParent
将节点从其父节点中移除,将节点从父节点树中移除。它还将节点从其父节点的子节点
数组中删除。发生此错误的原因是,在使用EnumerateChildrendesWithName
遍历数组的元素时,正在修改self.children
数组(使用removeFromParent
)。发生此错误的原因是,在遍历其元素时,正在修改集合。它与多线程无关
使用
removeFromParent
将节点从其父节点中移除,将节点从父节点树中移除。它还将节点从其父节点的子节点
数组中删除。出现此错误的原因是,您正在修改self.children
数组(使用removeFromParent
),同时使用EnumerateChildrenodesWithName
在数组元素上循环,我认为您的问题与多线程无关
问题是您正在使用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)
}
})
})
然后,完成迭代后,您可以调用removechildrenarinaray(u-nodes:[AnyObject]!)
onSKNode
,如前所述
您还可以查看更多详细信息。我认为您的问题与多线程无关 问题是您正在使用
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)
}
})
})
然后,完成迭代后,您可以调用removechildrenarinaray(u-nodes:[AnyObject]!)
onSKNode
,如前所述
您还可以查看更多详细信息。我建议您避免使用
enumerateChildNodesWithName
,因为它可能非常慢。或者,您可以创建名为lockGreen
的SKNode
并将lockGreen
节点添加到lockGreen
节点。然后,您可以使用在节点上迭代i(从:lockGreens.children.count-1,到:0,by:-1){…}
。由于循环向后迭代,您可以安全地从节点树和子节点
数组中删除节点。我建议您避免使用EnumerateChildNodeWithName
,因为它可能非常慢。或者,您可以创建名为lockGreen
的SKNode
并将lockGreen
节点添加到lockGreen
节点。然后,您可以使用在节点上迭代i(从:lockGreens.children.count-1,到:0,by:-1){…}
。因为循环是向后迭代的,所以可以安全地从节点树和子节点
数组中删除节点。