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

发布于 2024-09-15 18:00:15 字数 262 浏览 3 评论 0原文

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!");
    }
  }

Is there any way to check whether or not the current thread is the main thread in Objective-C?

I want to do something like this.

  - (void)someMethod
  {
    if (IS_THIS_MAIN_THREAD?) {
      NSLog(@"ok. this is main thread.");
    } else {
      NSLog(@"don't call this method from other thread!");
    }
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

酒几许 2024-09-22 18:00:15

查看 NSThread API 文档

有一些方法,例如

- (BOOL)isMainThread

+ (BOOL)isMainThread

+ (NSThread *)mainThread

Have a look at the NSThread API documentation.

There are methods like

- (BOOL)isMainThread

+ (BOOL)isMainThread

and + (NSThread *)mainThread

落墨 2024-09-22 18:00:15

在 Swift3 中

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

In Swift3

if Thread.isMainThread {
    print("Main Thread")
}
空名 2024-09-22 18:00:15

如果您希望某个方法在主线程上执行,您可以:

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

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

If you want a method to be executed on the main thread, you can:

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

    if ([NSThread isMainThread])
    {
        block();
    }
    else
    {
        dispatch_async(dispatch_get_main_queue(), block);
    }
}
单挑你×的.吻 2024-09-22 18:00:15

如果你想知道你是否在主线程上,你可以简单地使用调试器。在您感兴趣的行处设置一个断点,当您的程序到达该断点时,调用:

(lldb) thread info

这将显示有关您所在线程的信息:

( lldb) 线程信息
线程#1:tid = 0xe8ad0,0x00000001083515a0 MyApp`MyApp.ViewController.sliderMoved(发件人= 0x00007fd221486340,self = 0x00007fd22161c1a0)(ObjectiveC.UISlider)-> () + 112 at ViewController.swift:20,队列 = 'com.apple.main-thread',停止原因 = 断点 2.1

如果queue 的值为com.apple.main-thread,那么您位于主线程上。

If you want to know whether or not you're on the main thread, you can simply use the debugger. Set a breakpoint at the line you're interested in, and when your program reaches it, call this:

(lldb) thread info

This will display information about the thread you're on:

(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

If the value for queue is com.apple.main-thread, then you're on the main thread.

甜尕妞 2024-09-22 18:00:15

以下模式将确保方法在主线程上执行:

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

The following pattern will assure a method is executed on the 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
}
安静 2024-09-22 18:00:15
void ensureOnMainQueue(void (^block)(void)) {

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

        block();

    } else {

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            block();

        }];

    }

}

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

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

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

        block();

    } else {

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            block();

        }];

    }

}

note that i check the operation queue, not the thread, as this is a more safer approach

〗斷ホ乔殘χμё〖 2024-09-22 18:00:15

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

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

另外,

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

Two ways. From @rano's answer,

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

Also,

[[NSThread mainThread] isEqual:[NSThread currentThread]] ? NSLog(@"MAIN THREAD") : NSLog(@"NOT MAIN THREAD");
悲歌长辞 2024-09-22 18:00:15

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

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

For Monotouch / Xamarin iOS you can perform the check in this way:

if (NSThread.Current.IsMainThread)
{
    DoSomething();
}
else
{
    BeginInvokeOnMainThread(() => DoSomething());
}
猛虎独行 2024-09-22 18:00:15

详细信息

  • Swift 5.1、Xcode 11.3.1

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

获取当前 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

Details

  • Swift 5.1, Xcode 11.3.1

Solution 1. Detect any queue

Get current DispatchQueue?

Solution 2. Detect only main queue

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

Usage

if DispatchQueue.isRunningOnMainQueue { ... }

Sample

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

Result (log)

--------------------------------------------------------
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
眼眸里的那抹悲凉 2024-09-22 18:00:15

迅捷版


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

Swift Version


if (NSThread.isMainThread()) {
    print("Main Thread")
}
三生池水覆流年 2024-09-22 18:00:15

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

https://stackoverflow.com/a/34685535/1530581 检查此答案

let isOnMainQueue =
(dispatch_queue_get_label(dispatch_get_main_queue()) ==
dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL))

check this answer from https://stackoverflow.com/a/34685535/1530581

剩一世无双 2024-09-22 18:00:15
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") }
}
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") }
}
为你鎻心 2024-09-22 18:00:15

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

第一个想法出现在我身上,当我需要这个功能时,这行是:

dispatch_get_main_queue() == dispatch_get_current_queue();

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

[NSThread isMainThread];

我的解决方案快2.5倍。

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

UPDATE: seems that is not correct solution, according to queue.h header as mentioned @demosten

The first thought was brought to me, when I was needed this functionality was the line:

dispatch_get_main_queue() == dispatch_get_current_queue();

And had looked to the accepted solution:

[NSThread isMainThread];

mine solution 2.5 times faster.

PS And yes, I'd checked, it works for all threads

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文