2016-08-18 1 views
3

Après avoir lu tant de messages à propos de parallèle et concurrentes, je continue de confondre ce qui est la bonne façon d'extraire des données. Par exemple, dans mon projet, j'ai un bouton permettant à l'utilisateur d'extraire des données. Mon code est quelque chose comme ci-dessous.dispatch_async vs dispatch_sync dans les données d'extraction. Swift

var array = [Int]() 
func fetchData() { 

    .... 
    .... 
    response(objects: [object], error: NSError?) { 
     for object in objects { 
      array.append(object.number) // assume object.number return an Int 
     } 

     // confuse here. Should I use async here because I am worry if the user 
     // click the fetchData button more than one time, the append and make 
     // function will be happened at the same time. Or, is there anything I 
     // made a wrong assumption? I guess I need a serial operation. Correct? 

     dispatch_async(dispatch_get_main_queue()) { 
      makeCollectionView() // using the data in array 
     } 
    } 
} 

MISE À JOUR

Essayé pour exécuter ce code. 10000-19999 est exécuté après 0-9999. Il semble que la deuxième async n'arrêtera pas le premier async à traiter son opération.

dispatch_async(dispatch_get_main_queue(), {() -> Void in 
    for i in 0 ..< 10000 { 
     print(i) 
    } 
}) 
dispatch_async(dispatch_get_main_queue(), {() -> Void in 
    for i in 10000 ..< 20000 { 
     print(i) 
    } 
}) 

Répondre

0

GCD fournit des files d'attente pour l'exécution des tâches. Les files d'attente peuvent être de deux types - concurrentes ou série. Dans les tâches de file d'attente série, exécutez-en une à la fois (dans l'ordre FIFO), dans la file d'attente concurrente plusieurs tâches à la fois.

Pour empêcher l'utilisateur d'extraire des données pendant l'exécution d'une tâche d'extraction, il est nécessaire de ne pas soumettre la tâche d'extraction à la file d'attente à ce moment. Peu importe le type de file d'attente - concurrent ou série.

var array = [Int]() 
var isFethingData = false 

func fetchData() { 
    if !isFethingData { 
     isFethingData = true 
     dispatch_async(queueForFetchData) { 
      … 
      response(objects: [object], error: NSError?) { 
       for object in objects { 
        array.append(object.number) 
       } 

       dispatch_async(dispatch_get_main_queue()) { 
        makeCollectionView() 
       } 
       isFethingData = false 
      } 
    } 
} 

dispatch_async et dispatch_sync est des fonctions qui lui soumettent des tâches à la queue. La différence est que dispatch_async revient immédiatement après que la tâche a été soumise, mais dispatch_sync attendez la fin de la tâche. Par exemple:

print("\(NSDate()) qq") 
dispatch_sync(queue) { 
    // … some code which runs for 10 minutes. 
    print("\(NSDate()) ee") 
} 
print("\(NSDate()) ww") 
// 2016-08-18 16:02:00 qq 
// 2016-08-18 16:12:00 ee 
// 2016-08-18 16:12:00 ww 


print("\(NSDate()) qq") 
dispatch_async(queue) { 
    // … some code which runs for 10 minutes. 
    print("\(NSDate()) ee") 
} 
print("\(NSDate()) ww") 
// 2016-08-18 16:02:00 qq 
// 2016-08-18 16:02:00 ww 
// 2016-08-18 16:12:00 ee 
+0

Merveilleuse réponse pour effacer ma confusion. Merci –

+0

Opps. Encore une question. Si j'appelle deux fois dispatch_async (queue) {makeCollectionView()}, le second makeCollectionView sera exécuté juste après que le premier ou le second arrêtera immédiatement le premier et s'exécutera? si elle arrête le premier immédiatement, y a-t-il une fonction que je peux mettre comme première tâche à faire en file d'attente? –

+0

Mise à jour des informations –

1

Pour améliorer les performances, tout ce qui implique l'interface utilisateur doit s'exécuter sur le thread principal. Donc, fondamentalement:

dispatch_async(dispatch_get_main_queue()) { 
     //anything that involves UI 
    }