2010-08-23 107 views
96

有什么方法可以检查当前线程是否是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!"); 
    } 
    } 
+0

什么是错的有关调用其他线程的方法? – 2017-10-17 16:12:31

回答

143

看看NSThread API documentation

有喜欢

- (BOOL)isMainThread

+ (BOOL)isMainThread

+ (NSThread *)mainThread

+2

谢谢!这就是我想要的。 – 2010-08-23 10:14:41

-2

方法UPDATE:似乎是不正确的解决方案,根据queue.h标头,如@demosten

提到

首先想到的是带给我的,当我需要这个功能,是线:

dispatch_get_main_queue() == dispatch_get_current_queue(); 

而且已经看了接受的解决方案:

[NSThread isMainThread]; 

矿山解决方案快2.5倍。

PS是的,我会检查,它适用于所有线程

+3

有意义 - 您的方法绕过obj-c运行时消息传递系统的开销。虽然如果你使用这种技术,我会说它有一个不好的代码味道,也许是过早的优化。 – ArtOfWarfare 2013-08-21 22:29:34

+4

dispatch_get_current_queue()从IOS 6.0 – 2013-10-21 09:09:01

+30

弃用您可以在苹果的queue.h头的描述,其中dispatch_get_current_queue()的定义是这样说的: '当dispatch_get_current_queue()被调用主线程,它可以 或可能不会返回与dispatch_get_main_queue()相同的值。比较 这两种方法并不是测试代码是否在 主线程上执行的有效方法.' – demosten 2014-01-16 16:19:53

6

下面的模式将保证一个方法是在主线程上执行:

- (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'将自动使用将代码段粘贴到的方法old•ᴥ•ʔ – 2017-11-25 02:41:17

12

如果你想有一个方法是在主线程上执行,您可以:

- (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

回答旧问题可以获益从解释新答案如何与现有答案不同。 – 2015-01-15 18:39:12

+1

这是矫枉过正,如果某些工作必须在主线程上完成,那么在检查您是否在主线程中没有用处。只要做到'NSOperationQueue.mainQueue()。addOperationWithBlock {//你的工作在这里}' – Eric 2015-04-14 14:04:16

+0

@Eric我同意,但如果你想要什么方法,如果已经在主线程的立即执行?在你的建议中,该方法总是被调度以便稍后通过主操作队列执行。 – boherna 2016-01-26 19:01:30

11

如果你想知道你是否是在主线程上,你可以简单地使用调试器。设置在你感兴趣的线路断点,当你的程序达到它,称之为:

(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,那么您位于主线程中。

2

两种方式。从@拉诺的回答,

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

此外,

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

对于MonoTouch的/ Xamarin的iOS,你可以用这种方式进行检查:

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

斯威夫特版本


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

在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(); 

     }]; 

    } 

} 

注意,我检查作业队列,而不是线程,因为这是一个更安全的方法

+0

这应该是被接受的答案,主线程!=主队列 – railwayparade 2018-02-06 06:12:53