Ответ 1
Посмотрите NSThread
документацию по API.
Существуют такие методы, как
- (BOOL)isMainThread
+ (BOOL)isMainThread
и + (NSThread *)mainThread
Есть ли способ проверить, является ли текущий поток основным потоком в Objective-C?
Я хочу сделать что-то вроде этого.
- (void)someMethod
{
if (IS_THIS_MAIN_THREAD?) {
NSLog(@"ok. this is main thread.");
} else {
NSLog(@"don't call this method from other thread!");
}
}
Посмотрите NSThread
документацию по API.
Существуют такие методы, как
- (BOOL)isMainThread
+ (BOOL)isMainThread
и + (NSThread *)mainThread
Если вы хотите, чтобы метод выполнялся в основном потоке, вы можете:
- (void)someMethod
{
dispatch_block_t block = ^{
// Code for the method goes here
};
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_async(dispatch_get_main_queue(), block);
}
}
Если вы хотите узнать, находитесь ли вы в основном потоке, вы можете просто использовать отладчик. Установите точку останова на интересующую вас линию, и когда ваша программа достигнет ее, вызовите это:
(lldb) thread info
Здесь будет отображаться информация о потоке, в котором вы находитесь:
(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
Если значение queue
равно com.apple.main-thread
, вы находитесь в основном потоке.
В Swift3
if Thread.isMainThread {
print("Main Thread")
}
Следующий шаблон гарантирует, что метод будет выполняться в основном потоке:
- (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
}
Два способа. Из ответа @rano,
[[NSThread currentThread] isMainThread] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
Кроме того,
[[NSThread mainThread] isEqual:[NSThread currentThread]] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
Для Monotouch/Xamarin iOS вы можете выполнить проверку таким образом:
if (NSThread.Current.IsMainThread)
{
DoSomething();
}
else
{
BeginInvokeOnMainThread(() => DoSomething());
}
Быстрая версия
if (NSThread.isMainThread()) {
print("Main Thread")
}
void ensureOnMainQueue(void (^block)(void)) {
if ([[NSOperationQueue currentQueue] isEqual:[NSOperationQueue mainQueue]]) {
block();
} else {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
block();
}];
}
}
Обратите внимание, что я проверяю очередь операций, а не поток, так как это более безопасный подход
let isOnMainQueue = (dispatch_queue_get_label (dispatch_get_main_queue()) == dispatch_queue_get_label (DISPATCH_CURRENT_QUEUE_LABEL))
проверить этот ответ fooobar.com/questions/60226/...
UPDATE: кажется, что это неправильное решение, согласно заголовку queue.h, как указано @demosten
Первая мысль была доведена до меня, когда мне была нужна эта функциональность, была строка:
dispatch_get_main_queue() == dispatch_get_current_queue();
И посмотрел на принятое решение:
[NSThread isMainThread];
в 2,5 раза быстрее.
PS И да, я проверил, он работает для всех потоков