Quelle est la différence entre les appels synchrones et asynchrones dans L'Objectif-C, par rapport aux appels multi-threading?
pour la plus longue période, j'ai pensé que asynchrone était synonyme de lancer quelque chose sur un thread de fond, tandis que synchrone signifiait sur le thread principal (bloquant les mises à jour et les interactions de L'interface utilisateur). Je comprends que ne pas tourner sur le thread principal pour les actions coûteuses est parce qu'il ne permet pas les actions UI à se produire que le thread principal est occupé, mais pourquoi est-ce que synchrone gênant?
cependant, il est venu à mon attention depuis que vous pouvez faire des appels asynchrones sur le thread principal, et les appels synchrones sur les threads d'arrière-plan.
j'entends toujours les gens dire de ne pas utiliser les appels coûteux de façon synchrone ou sur le fil principal, car cela bloquera L'interface utilisateur pour l'utilisateur. Est-ce que ce sont deux questions distinctes que je devrais m'assurer de ne pas faire? Quelles sont les différences?
7 réponses
quand vous invoquez quelque chose de synchrone, cela signifie que le thread qui a initié cette opération attendra que la tâche se termine avant de continuer. Asynchrone signifie qu'il n'attendra pas.
ayant dit que, lorsque les gens suggèrent que vous effectuez un processus lent ou coûteux de façon asynchrone, ils suggèrent implicitement non seulement que vous devez l'exécuter de façon asynchrone, mais que vous devez le faire sur un fil de fond. L'objectif est de libérer le principal thread de sorte qu'il puisse continuer à répondre à l'interface utilisateur (plutôt que de geler), de sorte que vous envoyez des tâches à un thread de fond de façon asynchrone.
Donc, il y a deux parties. Tout d'abord, en utilisant GCD comme exemple, vous saisissez une file d'attente d'arrière-plan (soit vous saisissez l'une des files d'attente d'arrière-plan globales, soit vous créez la vôtre):
// one of the global concurrent background queues
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// or you could create your own serial background queue:
//
// dispatch_queue_t queue = dispatch_queue_create("com.domain.app.queuename", 0);
Deuxièmement, vous envoyez vos tâches dans cette file d'attente de façon asynchrone:
dispatch_async(queue, ^{
// the slow stuff to be done in the background
});
le le schéma pour les files d'attente d'opération est très similaire. Créez une file d'attente d'opération et ajoutez des opérations à cette file d'attente.
en réalité, la distinction synchrone vs asynchrone est complètement différente de la distinction queue principale vs queue de fond. Mais quand les gens parlent de "lancer un processus lent de façon asynchrone", ils disent vraiment "exécuter un processus lent de façon asynchrone sur une file d'attente en arrière-plan."
"Synchrone" signifie essentiellement "dans l'ordre." fondamentalement, quand vous faites une opération synchrone, tout ce qui vient plus tard doit attendre la fin de l'opération avant qu'ils puissent commencer.
à L'inverse, "asynchrone" signifie plus ou moins " pas en ordre." quand vous faites quelque chose d'asynchrone, le code suivant peut s'exécuter immédiatement et l'opération asynchrone sera exécuté...de temps en temps. Il peut être exécuté en parallèle avec le reste du code sur un autre thread. Il pourrait tout simplement être prévu pour une autre fois sur le même fil.
le concept de synchronicité n'a rien à voir avec des fils particuliers, en soi. C'est juste pour savoir si vous devez attendre pour une opération de finition ou pas.
où le fil conducteur vient dans ce d'une grande manière est dans les programmes de cacao (Touch). L'AppKit exécute l'événement principal boucle sur le thread principal, donc si le thread principal attend qu'une opération soit terminée, il ne peut traiter aucune entrée ou mettre à jour L'interface utilisateur. Si vous avez un morceau de code sur un thread de fond, cependant, l'exécution du code synchrone ne bloquera pas la boucle d'événement principale , parce que ce n'est pas le thread principal qui attend que l'opération synchrone soit terminée.
de même, une opération asynchrone de longue durée à partir d'un fil de fond que vous placez sur le thread principal peut causer des problèmes, car bien que le thread d'arrière-plan ne va pas attendre que l'opération se termine, il prend encore du temps sur le thread principal où la boucle d'événement doit fonctionner.
prenons quelques exemples simples:
appel asynchrone avec multithreading:
// Methods gets called in different thread and does not block the current thread. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler: ^(NSURLResponse *response, NSData *data, NSError *error) { }];
appel synchrone avec multithreading:
//Do something dispatch_sync(queue, ^{ //Do something else }); //Do More Stuff
ici vous avez / / faire quelque chose //faire quelque chose d'autre et ///faire plus de choses faites consécutivement même si / / faire quelque chose d'autre est fait sur un fil différent.
généralement, quand les gens utilisent fil différent, le but est que quelque chose puisse être exécuté sans attendre. Disons que vous voulez télécharger une grande quantité de données, mais que vous voulez que L'interface reste fluide.
par conséquent, dispatch_sync est rarement utilisé. Mais il est là. Personnellement, j'ai jamais utilisé ça. Pourquoi ne pas demander un exemple de code ou de projet qui utilise dispatch_sync.
appel asynchrone avec un fil:
[self performSelector:@selector(doSomething) withObject:nil afterDelay:0];
ici runloop courant à compléter avant que 'doSomething' ne soit appelé. En d'autres termes, la pile d'appels courante peut être complétée (la méthode courante retourne) avant que 'doSomething' ne soit appelé.
appel synchrone avec un fil:
[self doSomething];
Je ne pense pas que vous ayez besoin d'explication pour ça.
en général, l'activité asynchrone n'est pas synonyme de filetage, mais dans iOS ils sont mis en œuvre en utilisant cette façon. Ses pas vrai pour toutes les langues. Nous gérons généralement différentes tâches asynchrones en utilisant des boucles d'exécution.
signifie asynchrone signifie hors ligne, synchrone signifie dans la ligne. Vous pouvez effectuer des tâches synchrones et bloquer plusieurs fils à la fois.
Si vous êtes dans un thread d'arrière-plan et souhaitez mettre à jour tout un tas de l'interface utilisateur que vous appelez le thread principal dans un dispatch
file d'attente. Si vous appelez dispatch_sync
, alors le code que vous êtes actuellement dans waits pour le dispatch
à compléter, bloquant ainsi le fil d'arrière-plan que vous êtes dans et bloquant L'UI tandis que il met à jour le thread principal.
mais si vous appelez dispatch_async
le thread d'arrière-plan continuerait avec le reste du code indiqué et le thread principal exécuterait le bloc demandé dispatch
.
on peut dire la même chose dans le fil principal. si vous appelez un dispatch_sync
à partir du thread principal dans une file d'attente globale ou personnalisée, il bloquera le thread principal pendant qu'il exécute le code dans un thread séparé. Je ne peux pas dire que je connais un cas où être utilisé, mais il est sûrement possible.
chaque fois que vous avez le code de calcul, le code webservice, le code fetching, ce qui n'affecte pas L'UI, il est préférable de le faire dans un thread séparé. Pour ce genre de choses que je ferais une dispatch_async
un fil. Ensuite, lorsque ce code est terminé, j'exécuterais un dispatch_async
de nouveau dans le thread principal pour lui dire de mettre à jour L'UI avec ce que je viens de calculer.
synchrone signifie blocage, asynchrone signifie qu'il sera terminé à une date ultérieure (peut-être maintenant) sans bloquer ce que vous faites actuellement.
Cette discussion assez beaucoup de réponses: Asynchrone vs Multithreading - Est-il une différence?
dans le cas général, un appel asynchrone ne crée pas nécessairement un nouveau fil. C'est une façon de le mettre en œuvre, avec un pool de threads préexistant ou un processus externe étant d'autres façons. Cela dépend fortement du langage, du modèle d'objet (s'il y en a un) et de l'environnement run time.
asynchrone juste signifie que le fil appelant ne s'assoit pas et n'attend pas la réponse, pas plus que l'activité asynchrone ne se produit dans le fil appelant.
donc fondamentalement, d'autres activités peuvent se produire en attendant quelque chose à charger, mais il peut ou ne peut pas être fait sur des fils séparés.
swift 3, 4, 4,2 synchrone le fil qui a amorcé cette opération attendra que la tâche soit terminée avant de continuer.
DispatchQueue.main.sync {
}
asynchrone signifie que vous avez terminé une tâche en arrière-plan et que vous pouvez vous en servir pour vous informer.
DispatchQueue.main.async {
}
synchrone : attend jusqu'à ce que la tâche soit terminée
performBlockAndWait, est synchrone. Le thread principal s'arrêtera et attendra une réponse du bloc avant qu'il ne continue avec la prochaine opération.
asynchrone : exécute une tâche en arrière-plan et peut vous en aviser lorsqu'elle est terminée.
perforblock, méthode est celle qui est asynchrone. Ce qui signifie qu'il peut fonctionner à tout moment et la fonction qui l'a appelé peut continuer sans avoir besoin de savoir si le bloc a réussi ou non. Le thread principal peut continuer même si le bloc est toujours ou n'a même pas commencé à fonctionner.