programing

현재 스레드가 주 스레드인지 확인합니다.

starjava 2023. 6. 1. 21:39
반응형

현재 스레드가 주 스레드인지 확인합니다.

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

API 설명서를 참조하십시오.

다음과 같은 방법이 있습니다.

- (BOOL)isMainThread

+ (BOOL)isMainThread

그리고.+ (NSThread *)mainThread

인 스위프트3

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

메인 스레드에서 메서드를 실행하려면 다음을 수행합니다.

- (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그러면 당신은 메인 스레드에 있습니다.

다음 패턴을 사용하면 메인 스레드에서 메서드가 실행됩니다.

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

        }];

    }

}

스레드가 아닌 작업 대기열을 확인합니다. 이것이 더 안전한 접근 방식이기 때문입니다.

두 가지 방법.@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());
}

세부 사항

  • Swift 5.1, Xcode 11.3.1

해결책 1.대기열 탐지

현재 디스패치 대기열을 가져오시겠습니까?

해결책 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

스위프트 버전


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

isOnMainQueue = (syspatch_get_label(syspatch_main_label(syspatch_main_label)) == dispatch_queue_get_label(DISPATCH_CURRENT_queue_LABEL)

https://stackoverflow.com/a/34685535/1530581 에서 이 답변을 확인합니다.

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

대기열에 따르면 업데이트: 올바른 솔루션이 아닌 것 같습니다.@demosten에서 언급한 것처럼 h 헤더

제가 필요로 했을 때, 이 기능은 다음과 같이 생각했습니다.

dispatch_get_main_queue() == dispatch_get_current_queue();

그리고 수용된 해결책을 찾았습니다.

[NSThread isMainThread];

광산 용액의 2.5배 더 빠릅니다.

PS 및 네, 확인했습니다. 모든 스레드에서 작동합니다.

언급URL : https://stackoverflow.com/questions/3546539/check-whether-or-not-the-current-thread-is-the-main-thread

반응형