답변:
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);
}
}
NSOperationQueue.mainQueue().addOperationWithBlock { //your work here }
dispatch_sync()
대신 사용하면 댓글에서 포인트가 더 강해질 것 dispatch_async()
입니다.
메인 스레드에 있는지 여부를 알고 싶다면 디버거를 사용하면됩니다. 관심있는 줄에 중단 점을 설정하고 프로그램이 여기에 도달하면 다음을 호출하십시오.
(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
}
_cmd
자동 코드 조각에 붙여 넣기하는 방법을 사용합니다 ʕ • ᴥ • ʔ
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))
https://stackoverflow.com/a/34685535/1530581 에서이 답변을 확인 하십시오.
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
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에서 언급했듯이 queue.h 헤더에 따르면 올바른 해결책이 아닌 것 같습니다 .
이 기능이 필요했을 때 첫 번째 생각은 다음과 같습니다.
dispatch_get_main_queue() == dispatch_get_current_queue();
그리고 수용된 솔루션을 찾았습니다.
[NSThread isMainThread];
광산 솔루션 2.5 배 더 빠릅니다.
PS 그리고 예, 확인했습니다. 모든 스레드에서 작동합니다.
When dispatch_get_current_queue() is called on the main thread, it may or may not return the same value as dispatch_get_main_queue(). Comparing the two is not a valid way to test whether code is executing on the main thread.