2016-10-16 1 views
0

Je n'arrive pas à comprendre comment fonctionnent les files d'attente de répartition ou les gestionnaires de tâches dans swift 3. Mon problème spécifique est le suivant: je rencontre des problèmes de performances et souhaite exécuter plusieurs blocs de codez en parallèle et attendez pour quitter la fonction jusqu'à ce que tous les blocs se terminent. J'ai essayé d'exécuter simplement les blocs de manière asynchrone en arrière-plan, mais ensuite j'essaie d'utiliser xxx pendant qu'il est en train de muter parce que j'énumère sur les mêmes tableaux ou enumerateChildNodes (...) étant gérés sur les files d'attente asynchrones. J'essaie de gérer la minimisation des nœuds SpriteKit pour améliorer les fps. Voici un exemple des blocs de code que je veux courir en parallèle et les attendre:Exécution simultanée de blocs de code dans Swift 3 Fonction suivie d'attente d'achèvement

func determinePlatformNodesToUse() { 

    // Code Block 1: 
    for platform in platformArray { 
     addPlatformNode(platform, leftDistance: leftDistance, rightDistance: rightDistance) 
    } 

    // Also part of Code Block 1: 
    // resort the platform nodes to guarantee position sequence 
    currentPlatformNodeArray.sort(by: { $0.position.x < $1.position.x }) 

    // Code Block 2: 
    for character in characterArray { 
     if character.type == CharacterType.Enemy { 
      addCharacterNode(character, leftDistance: leftDistance, rightDistance: rightDistance) 
     } 
    } 

    // Code block 3 
    // put all the enemies into an array for update processing will be added in addCharacterNode 
    currentMotionEnemyNodeArray.removeAll() 

    // Also part of Code block 3 
    foregroundNode.enumerateChildNodes(withName: CharacterType.Enemy.rawValue, using: { 
     (node, stop) in 
     if let enemy = node as? CharacterNode { 
      if enemy.motionType != .Stand { // dont use .Stand as they dont have motion 
       self.currentMotionEnemyNodeArray.append(enemy) 
      } 
     } 
    }) 

    // Code Block 4 
    for actionSceneObject in actionSceneObjectArray { 
     addActionSceneObjectNode(actionSceneObject, leftDistance: leftDistance, rightDistance: rightDistance) 
    } 

    // At this point, wait until all blocks 1-4 above have finished 

    // Run blocks 5 - 8 code in all in parallel 

    // wait until blocks 5 - 8 have finished and then leave the function 
    } 
+0

Salut, s'il vous plaît laissez-moi savoir si votre problème est résolu – KrishnaCA

Répondre

0

Vous pouvez obtenir ce que vous essayez de faire en utilisant NSOperation. Il peut se faire de la manière suivante:

func determinePlatformNodesToUse(completion: (_ success: Bool) -> Void) { 

    let queue:OperationQueue = OperationQueue() 
    queue.name = "com.SOQA.SOQA.name" 
    queue.qualityOfService = QualityOfService.default 
    queue.maxConcurrentOperationCount = 6 

    let operation01:BlockOperation = BlockOperation { 
     // Code Block - 1 
    } 

    let operation02:BlockOperation = BlockOperation { 
     // Code Block - 2 
    } 

    let operation03:BlockOperation = BlockOperation { 
     // Code Block - 3 
    } 

    let operation04:BlockOperation = BlockOperation { 
     // Code Block - 4 
    } 

    let operation05:BlockOperation = BlockOperation { 
     // Code Block - 5 
    } 

    let operation06:BlockOperation = BlockOperation { 
     // Code Block - 6 
    } 

    let operation07:BlockOperation = BlockOperation { 
     // Code Block - 7 
    } 

    let operation08:BlockOperation = BlockOperation { 
     // Code Block - 8 
    } 

    operation05.addDependency(operation01) 
    operation05.addDependency(operation02) 
    operation05.addDependency(operation03) 
    operation05.addDependency(operation04) 

    operation06.addDependency(operation01) 
    operation06.addDependency(operation02) 
    operation06.addDependency(operation03) 
    operation06.addDependency(operation04) 

    operation07.addDependency(operation01) 
    operation07.addDependency(operation02) 
    operation07.addDependency(operation03) 
    operation07.addDependency(operation04) 

    operation08.addDependency(operation01) 
    operation08.addDependency(operation02) 
    operation08.addDependency(operation03) 
    operation08.addDependency(operation04) 

    queue.addOperations([operation01, operation02, operation03, operation04, operation05, operation06, operation07, operation08], waitUntilFinished: true) 
} 

Ne hésitez pas à commenter si vous avez des doutes à l'aide de cet exemple. N'hésitez pas à suggérer des modifications pour améliorer cela :)

+0

Cette approche fonctionne très bien la première fois, mais la deuxième fois, je reçois une exception de mutation. Cette file d'attente s'exécute-t-elle sur le thread principal? Sinon, je pense que la fonction de mise à jour est appelée à nouveau pendant que la file d'attente est encore en cours d'exécution. *** Terminaison de l'application due à une exception non interceptée 'NSGenericException', raison: '*** Collection <__ NSArrayM: 0x17405bcc0> a été muté lors de son énumération.' *** Première pile d'appels: – Jacksonsox