В настоящее время я разрабатываю игру, в которой сферы падают с неба. Собирая сферы, вы получаете очки, и после определенного количества очков все сферы ускоряются до другой скорости.Swift - многопоточная многопоточная обработка GCD, «мутированная при перечислении»
- Новые сферы непрерывно добавляют в массив (4 Spheres внутри каждого SKNode).
- Когда они ускоряются, я повторяю массив, чтобы увеличить скорость всех из них.
- Когда сферы выпадают из экрана, я удаляю их из массива.
class GameScene: SKScene, SKPhysicsContactDelegate {
...
var allActiveNodes = Array<SKNode>()
private let concurrentNodesQueue = dispatch_queue_create(
"com.SphereHunt.allActiveNodesQueue", DISPATCH_QUEUE_CONCURRENT)
...
//1. This is where the new spheres are added to the Array via a new thread
func addSpheres(leftSphere: Sphere, middleLeftSphere: Sphere, middleRightSphere: Sphere, rightSphere: Sphere){
...
dispatch_barrier_async(self.concurrentNodesQueue){
self.allActiveNodes.append(containerNode)
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(queue) {
//Set the new spheres in motion
self.runPastAvatar(containerNode)
}
}
//2. This function starts a thread that will increase the speed of all active spheres
func increaseSpeed20percent(){
durationPercentage = durationPercentage * 0.8
dispatch_sync(self.concurrentNodesQueue){
let copyAllActiveNodes = self.allActiveNodes
let count = copyAllActiveNodes.count
for index in 0...count-1{
let node = copyAllActiveNodes[index]
node.removeAllActions()
self.runPastAvatar(node)
}
}
}
//3. This method removes the sphere that is not in screen anymore from the Array
func removeLastNode(node: SKNode){
dispatch_barrier_async(self.concurrentNodesQueue){
self.allActiveNodes.removeAtIndex(0)
node.removeFromParent()
println("Removed")
}
}
Я не уверен, если я понял НОД правильно, я попробовал несколько решений, и это один я был уверен, что будет работать. Я всегда получаю такое же сообщение об ошибке:
*** Terminating app due to uncaught exception 'NSGenericException',
reason: '*** Collection <__NSArrayM: 0x17004c9f0> was mutated while being enumerated.'
Как заставить потоки не мешать друг другу при работе с массивом?
Я пробовал вызывать цикл с dispatch_barrier_sync, но проблема остается. – hardyfelix
Я прокомментировал все, что имело отношение к массиву, и у меня все еще такое же сообщение об ошибке. Это очень странно, потому что никакой другой массив не манипулируется подобным образом. Как я могу отладить это? Сообщение об ошибке «Collection <__ NSArrayM: 0x17004c9f0> ...» показывает идентификатор массиву, но при просмотре кода массивы не получают никаких идентификаторов. Как я могу найти конкретный массив, который находится за ручкой, тем самым давая это сообщение об ошибке? – hardyfelix
Я прокомментировал буквально все. Теперь я начинаю только 1 поток, который добавляет больше сфер, а затем спит в течение продолжительности. Я всегда получаю то же сообщение об ошибке, когда поток спит, ничего не работает, а спящий поток. Может ли быть проблема с функцией сна внутри потока? Но ничего подобного не должно приводить к тому, что «<__ NSArrayM: 0x170048e20> мутировался при перечислении». – hardyfelix