web-dev-qa-db-fra.com

Appeler une méthode sur le thread principal?

Tout d'abord, j'écris du code pour iPhone. Je dois pouvoir appeler une méthode sur le thread principal sans utiliser performSelectorOnMainThread. La raison pour laquelle je ne veux pas utiliser performSelectorOnMainThread est que cela pose problème lorsque j'essaie de créer une maquette pour les tests unitaires.

[self performSelectorOnMainThread:@Selector(doSomething) withObject:nil];

Le problème est que ma maquette sait comment appeler doSomething mais elle ne sait pas comment appeler performSelectorOnMainThread.

Alors, une solution?

73
aryaxt

Objectif-C

dispatch_async(dispatch_get_main_queue(), ^{
  [self doSomething];
});

rapide

dispatch_async(dispatch_get_main_queue()) {
   self.doSomething()
}

Swift 3 et 4

DispatchQueue.main.async {
   self.doSomething()
}
236
aryaxt

Il y a un dicton dans le logiciel qui ajoute que l'ajout d'une couche d'indirection résoudra presque tout.

Demandez à la méthode doSomething d'être un shell d'indirection qui ne fait qu'un performSelectorOnMainThread pour appeler la méthode really_doSomething pour effectuer le travail Something réel. Ou, si vous ne voulez pas changer votre méthode doSomething, demandez à l'unité de test simulée d'appeler une méthode doSomething_redirect_Shell pour faire quelque chose de similaire.

2
hotpaw2

Et maintenant dans Swift 3:

DispatchQueue.main.async{
   self.doSomething()
}
1
RomOne

Voici une meilleure façon de procéder dans Swift:

runThisInMainThread { () -> Void in
    // Run your code
    self.doSomething()
}

func runThisInMainThread(block: dispatch_block_t) {
    dispatch_async(dispatch_get_main_queue(), block)
}

Il est inclus en tant que fonction standard dans mon référentiel, consultez-le: https://github.com/goktugyil/EZSwiftExtensions

1
Esqarrouth