检查当前线程是否是主线程

时间:2010-08-23 10:07:54

标签: objective-c iphone multithreading cocoa xamarin.ios

有没有办法检查当前线程是否是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!");
    }
  }

13 个答案:

答案 0 :(得分:155)

查看NSThread API documentation

有像

这样的方法

- (BOOL)isMainThread

+ (BOOL)isMainThread

+ (NSThread *)mainThread

答案 1 :(得分:21)

如果要在主线程上执行方法,可以:

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

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

答案 2 :(得分:15)

在Swift3中

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

答案 3 :(得分:12)

如果您想知道自己是否在主线程上,可以直接使用调试器。在您感兴趣的行设置一个断点,当您的程序到达时,请调用:

(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,那么您就是主线程。

答案 4 :(得分: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
}

答案 5 :(得分:3)

void ensureOnMainQueue(void (^block)(void)) {

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

        block();

    } else {

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            block();

        }];

    }

}

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

答案 6 :(得分:2)

两种方式。来自@ rano的回答,

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

此外,

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

答案 7 :(得分:2)

对于Monotouch / Xamarin iOS,您可以通过以下方式执行检查:

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

答案 8 :(得分:1)

Swift版

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

答案 9 :(得分:0)

  

让isOnMainQueue =   (dispatch_queue_get_label(dispatch_get_main_queue())==   dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL))

https://stackoverflow.com/a/34685535/1530581

查看此答案

答案 10 :(得分:0)

详细信息

  • Swift 5.1,Xcode 11.3.1

解决方案1.检测任何队列

Get current DispatchQueue?

解决方案2。仅检测主队列

import Foundation

extension DispatchQueue {

    private struct QueueReference { weak var queue: DispatchQueue? }

    private static let key: DispatchSpecificKey<QueueReference> = {
        let key = DispatchSpecificKey<QueueReference>()
        let queue = DispatchQueue.main
        queue.setSpecific(key: key, value: QueueReference(queue: queue))
        return key
    }()

    static var isRunningOnMainQueue: Bool { getSpecific(key: key)?.queue == .main }
}

用法

if DispatchQueue.isRunningOnMainQueue { ... }

样本

func test(queue: DispatchQueue) {
    queue.async {
        print("--------------------------------------------------------")
        print("queue label: \(queue.label)")
        print("is running on main queue: \(DispatchQueue.isRunningOnMainQueue)")
    }
}

test(queue: DispatchQueue.main)
sleep(1)
test(queue: DispatchQueue.global(qos: .background))
sleep(1)
test(queue: DispatchQueue.global(qos: .unspecified))

结果(日志)

--------------------------------------------------------
queue label: com.apple.root.background-qos
is running on main queue: false
--------------------------------------------------------
queue label: com.apple.root.default-qos
is running on main queue: false
--------------------------------------------------------
queue label: com.apple.main-thread
is running on main queue: true

答案 11 :(得分:0)

Here is a way to detect what the current queue is
extension DispatchQueue {
    //Label of the current dispatch queue.
    static var currentQueueLabel: String { String(cString: __dispatch_queue_get_label(nil)) }

    /// Whether the current queue is a `NSBackgroundActivityScheduler` task.
    static var isCurrentQueueNSBackgroundActivitySchedulerQueue: Bool { currentQueueLabel.hasPrefix("com.apple.xpc.activity.") }

    /// Whether the current queue is a `Main` task.
    static var isCurrentQueueMainQueue: Bool { currentQueueLabel.hasPrefix("com.apple.main-thread") }
}

答案 12 :(得分:-2)

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

第一个想法是带给我的,当我需要时,这个功能就是这一行:

dispatch_get_main_queue() == dispatch_get_current_queue();

并且已经找到了接受的解决方案:

[NSThread isMainThread];

我的解决方案速度提高了2.5倍。

PS是的,我已经检查过,它适用于所有线程