2010-08-23 13 views
96

¿Hay alguna manera de comprobar si el hilo actual es el hilo principal en Objective-C?Compruebe si el hilo actual es el hilo principal

Quiero hacer algo como esto.

- (void)someMethod 
    { 
    if (IS_THIS_MAIN_THREAD?) { 
     NSLog(@"ok. this is main thread."); 
    } else { 
     NSLog(@"don't call this method from other thread!"); 
    } 
    } 
+0

¿Qué hay de malo en llamar a un método desde otros hilos? –

Respuesta

143

Eche un vistazo a NSThread API documentation.

hay métodos como

- (BOOL)isMainThread

+ (BOOL)isMainThread

y + (NSThread *)mainThread

+2

Gracias! Eso es lo que quiero. –

-2

UPDATE: parece que no es la solución correcta, de acuerdo con la cabecera queue.h como se ha mencionado @demosten

El primer pensamiento fue llevado a mí, cuando me necesitaban esta funcionalidad era la línea:

dispatch_get_main_queue() == dispatch_get_current_queue(); 

Y había mirado a la solución aceptada:

[NSThread isMainThread]; 

solución mina de 2,5 veces más rápido.

PS Y sí, lo había comprobado, funciona para todos los hilos

+3

Tiene sentido: su método omite la sobrecarga del sistema de mensajes obj-c en tiempo de ejecución. Aunque si estás usando esta técnica, diría que tiene un mal olor a código, quizás el de la optimización prematura. – ArtOfWarfare

+4

dispatch_get_current_queue() está en desuso desde iOS 6.0 –

+30

Usted puede leer esto en la descripción de cabecera queue.h de Apple, donde se define dispatch_get_current_queue(): 'Cuando dispatch_get_current_queue() es llamado en el hilo principal, puede o no puede regresar el mismo valor que dispatch_get_main_queue(). Comparando , los dos no son una forma válida de comprobar si el código se está ejecutando en el hilo principal . – demosten

6

El siguiente patrón asegurará un método se ejecuta en el hilo principal:

- (void)yourMethod { 
    // make sure this runs on the main thread 
    if (![NSThread isMainThread]) { 
     [self performSelectorOnMainThread:_cmd/*@selector(yourMethod)*/ 
           withObject:nil 
          waitUntilDone:YES]; 
     return; 
    } 
    // put your code for yourMethod here 
} 
+0

'_cmd' usará automáticamente el método en el que se pega su fragmento en ʕ • ʔ –

12

si quieres un método sea ejecutado en el hilo principal, puede:

- (void)someMethod 
{ 
    dispatch_block_t block = ^{ 
     // Code for the method goes here 
    }; 

    if ([NSThread isMainThread]) 
    { 
     block(); 
    } 
    else 
    { 
     dispatch_async(dispatch_get_main_queue(), block); 
    } 
} 
+4

Las respuestas a preguntas antiguas pueden beneficiar de una explicación de cómo la nueva respuesta difiere de las respuestas existentes. –

+1

Esto es excesivo, si algún trabajo * debe * hacerse en el hilo principal, no sirve de nada verificar si está en el hilo principal o no. Solo haga 'NSOperationQueue.mainQueue(). AddOperationWithBlock {// su trabajo aquí}' – Eric

+0

@Eric Estoy de acuerdo, pero ¿y si desea la ejecución inmediata del método si ya está en el hilo principal? En su sugerencia, el método siempre se envía para que se ejecute posteriormente a través de la cola de operaciones principal. – boherna

11

Si usted quiere saber si está o no está en el hilo principal, puede simplemente usar el depurador. Establecer un punto de interrupción en la línea que le interesa, y cuando el programa llega a ella, llamar a esto:

(lldb) thread info

Esto mostrará información sobre el hilo estás en:

(lldb) thread info thread #1: tid = 0xe8ad0, 0x00000001083515a0 MyApp`MyApp.ViewController.sliderMoved (sender=0x00007fd221486340, self=0x00007fd22161c1a0)(ObjectiveC.UISlider) ->() + 112 at ViewController.swift:20, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1

Si el valor de queue es com.apple.main-thread, entonces está en el hilo principal.

2

De dos maneras.A partir de la respuesta de @ rano,

[[NSThread currentThread] isMainThread] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD"); 

Además,

[[NSThread mainThread] isEqual:[NSThread currentThread]] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD"); 
2

Para MonoTouch/Xamarin IOS se puede realizar la comprobación de esta manera:

if (NSThread.Current.IsMainThread) 
{ 
    DoSomething(); 
} 
else 
{ 
    BeginInvokeOnMainThread(() => DoSomething()); 
} 
1

Swift Versión


if (NSThread.isMainThread()) { 
    print("Main Thread") 
} 
11

En Swift3

if Thread.isMainThread { 
    print("Main Thread") 
} 
2
void ensureOnMainQueue(void (^block)(void)) { 

    if ([[NSOperationQueue currentQueue] isEqual:[NSOperationQueue mainQueue]]) { 

     block(); 

    } else { 

     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 

      block(); 

     }]; 

    } 

} 

tenga en cuenta que verifico la cola de operaciones, no el hilo, ya que este es un enfoque más seguro

+0

¡Esta debería ser la respuesta aceptada, hilo principal! = Cola principal – railwayparade

Cuestiones relacionadas