2011-04-09 15 views
52

Primero de todo estoy escribiendo código para iphone. Necesito poder llamar a un método en el hilo principal sin usar performSelectorOnMainThread. La razón por la que no quiero usar performSelectorOnMainThread es que causa problemas cuando intento crear un simulacro para pruebas unitarias.¿Llamar a un método en el hilo principal?

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

El problema es que mi maqueta sabe cómo llamar doSomething pero no sabe cómo llamar performSelectorOnMainThread.

¿Alguna solución?

Respuesta

181

Objective C

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

Swift

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

Swift 3 & Swift 4

DispatchQueue.main.async{ 
    self.doSomething() 
} 
+0

Usted acaba de hacer mi día con el código SWIFT 3. ¡Gracias! –

2

Hay un dicho en el software que agrega una capa de direccionamiento indirecto arreglará casi cualquier cosa.

Haga que el método doSomething sea un shell de indirección que solo realiza un performSelectorOnMainThread para llamar al método really_doSomething para que funcione el verdadero Something. O bien, si no desea cambiar su método doSomething, haga que la unidad de prueba simulada llame a un método doSomething_redirect_shell para hacer algo similar.

0

Aquí es una mejor manera de hacer esto en Swift:

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

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

Su incluido como una función estándar en mi repo, mira eso: https://github.com/goktugyil/EZSwiftExtensions

+0

Esto no es mejor de ninguna manera, creó una función que no hace más que llamar a otra. por cierto, la sintaxis rápida se puede simplificar aún más "() -> Void in" no es necesario – aryaxt

+0

Es más fácil de leer/escribir. Sí autocompletar agrega en "() -> Void in". ¿Hay alguna forma de desactivar este comportamiento de autocompletar en los cierres void> void? – Esqarrouth

+0

el nombre del método que tiene puede ser engañoso, parece que el bloque se ejecutará inmediatamente en el hilo principal, pero eso no es cierto. dispatch_async en la cola principal agrega el bloque de código al próximo runloop, este comportamiento importante está oculto detrás del método que se llama "runThisInMainThread – aryaxt

1

Y ahora en rápida 3:

DispatchQueue.main.async{ 
    self.doSomething() 
} 
Cuestiones relacionadas