Est-il possible de vérifier si oui ou non le thread actuel est le thread principal dans Objective-C?
Je veux faire quelque chose comme ça.
- (void)someMethod { if (IS_THIS_MAIN_THREAD?) { NSLog(@"ok. this is main thread."); } else { NSLog(@"don't call this method from other thread!"); } }
Consultez la documentation de l’API NSThread
.
Il existe des méthodes comme
- (BOOL)isMainThread
+ (BOOL)isMainThread
et + (NSThread *)mainThread
Si vous souhaitez qu’une méthode soit exécutée sur le thread principal, vous pouvez:
- (void)someMethod { dispatch_block_t block = ^{ // Code for the method goes here }; if ([NSThread isMainThread]) { block(); } else { dispatch_async(dispatch_get_main_queue(), block); } }
En swift3
if Thread.isMainThread { print("Main Thread") }
Si vous voulez savoir si vous êtes sur le thread principal ou non, vous pouvez simplement utiliser le débogueur. Définissez un point d’arrêt à la ligne qui vous intéresse et, lorsque votre programme y parvient, appelez ceci:
(lldb) thread info
Cela affichera des informations sur le thread sur lequel vous vous trouvez:
(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 la valeur de la queue
d’ queue
est com.apple.main-thread
, vous êtes sur le thread principal.
Le modèle suivant assurera qu’une méthode est exécutée sur le thread 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 }
Deux façons. De la réponse de @rano,
[[NSThread currentThread] isMainThread] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
Aussi,
[[NSThread mainThread] isEqual:[NSThread currentThread]] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
Pour Monotouch / Xamarin iOS, vous pouvez effectuer la vérification de cette manière:
if (NSThread.Current.IsMainThread) { DoSomething(); } else { BeginInvokeOnMainThread(() => DoSomething()); }
void ensureOnMainQueue(void (^block)(void)) { if ([[NSOperationQueue currentQueue] isEqual:[NSOperationQueue mainQueue]]) { block(); } else { [[NSOperationQueue mainQueue] addOperationWithBlock:^{ block(); }]; } }
notez que je vérifie la queue d’opération, pas le thread, car c’est une approche plus sûre
Version rapide
if (NSThread.isMainThread()) { print("Main Thread") }
let isOnMainQueue = (dispatch_queue_get_label (dispatch_get_main_queue ()) == dispatch_queue_get_label (DISPATCH_CURRENT_QUEUE_LABEL))
vérifiez cette réponse depuis https://stackoverflow.com/a/34685535/1530581
UPDATE: semble que ce n’est pas une solution correcte, selon l’en-tête queue.h mentionné @demosten
La première pensée m’a été apscope, quand j’avais besoin de cette fonctionnalité était la ligne:
dispatch_get_main_queue() == dispatch_get_current_queue();
Et avait regardé la solution acceptée:
[NSThread isMainThread];
la solution de mine 2,5 fois plus rapide.
PS Et oui, j’avais vérifié, ça marche pour tous les threads