Est-il possible de vérifier si 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!");
}
}
Jetez un coup d’œil à la NSThread
documentation de l’API .
Il y a 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);
}
}
Dans Swift3
if Thread.isMainThread {
print("Main Thread")
}
Si vous voulez savoir si vous êtes ou non sur le thread principal, vous pouvez simplement utiliser le débogueur. Définissez un point d'arrêt sur la ligne qui vous intéresse et, lorsque votre programme l'aura atteint, appelez ceci:
(lldb) thread info
Cela affichera des informations sur le fil 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 queue
est com.Apple.main-thread
, alors 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
}
void ensureOnMainQueue(void (^block)(void)) {
if ([[NSOperationQueue currentQueue] isEqual:[NSOperationQueue mainQueue]]) {
block();
} else {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
block();
}];
}
}
notez que je vérifie la file d'attente des opérations, pas le fil, comme c'est une approche plus sûre
Pour Monotouch/Xamarin iOS, vous pouvez effectuer le contrôle de la manière suivante:
if (NSThread.Current.IsMainThread)
{
DoSomething();
}
else
{
BeginInvokeOnMainThread(() => DoSomething());
}
Deux manières. De la réponse de @ rano,
[[NSThread currentThread] isMainThread] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
Également,
[[NSThread mainThread] isEqual:[NSThread currentThread]] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
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érifier cette réponse de https://stackoverflow.com/a/34685535/1530581