어떤 스레드에서나 콜백이 있습니다. 이 콜백을 받으면 메인 스레드에서 특정 작업을 수행하고 싶습니다.
이미 메인 스레드에 있는지 확인해야합니까, 아니면 아래 코드를 호출하기 전에이 확인을 수행하지 않으면 페널티가 있습니까?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
어떤 스레드에서나 콜백이 있습니다. 이 콜백을 받으면 메인 스레드에서 특정 작업을 수행하고 싶습니다.
이미 메인 스레드에 있는지 확인해야합니까, 아니면 아래 코드를 호출하기 전에이 확인을 수행하지 않으면 페널티가 있습니까?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
답변:
아니요, 이미 메인 스레드에 있는지 여부를 확인할 필요가 없습니다. 블록을 메인 큐에 디스패치하면 블록이 메인 스레드에서 직렬로 실행되도록 예약하는 것입니다. 해당 실행 루프가 실행될 때 발생합니다.
메인 스레드에 이미있는 경우 동작은 동일합니다. 블록이 예약되고 메인 스레드의 실행 루프가 실행될 때 실행됩니다.
async
다시 발송 하면 대기열이 실행되지만 예상되는 작업 타이밍을 망칠 수 있습니다 . 이러한에서 UI 코드로 viewDidLoad()
될 때까지 실행되지 후 뷰가 먼저 표시됩니다 .
위에서 설명한 비동기 디스패치 사례의 경우 메인 스레드에 있는지 확인할 필요가 없습니다. Bavarious에서 알 수 있듯이 이것은 메인 스레드에서 실행되도록 대기합니다.
그러나 a를 사용하여 위의 작업을 시도하고 dispatch_sync()
콜백이 기본 스레드에 있으면 해당 시점에서 애플리케이션이 교착 상태가됩니다. 이 동작은 코드를 이동할 때 놀랐 기 때문에 여기 에 내 대답에 이것을 설명합니다 -performSelectorOnMainThread:
. 내가 언급했듯이 도우미 함수를 만들었습니다.
void runOnMainQueueWithoutDeadlocking(void (^block)(void))
{
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
}
현재 사용중인 메소드가 현재 메인 스레드에없는 경우 메인 스레드에서 동기식으로 블록을 실행하고 블록이 있으면 인라인으로 실행합니다. 다음과 같은 구문을 사용하여이를 사용할 수 있습니다.
runOnMainQueueWithoutDeadlocking(^{
//Do stuff
});
dispatch_set_specific()
설명에 도움 이 될지 궁금합니다 . stackoverflow.com/a/12806754/19679 .
다른 답변에서 언급했듯이 기본 스레드의 dispatch_async가 좋습니다.
그러나 유스 케이스에 따라 단점을 고려할 수있는 부작용이 있습니다. 블록이 큐에서 스케줄되므로 제어가 실행 루프로 돌아갈 때까지 실행되지 않으므로 지연 효과가 있습니다. 블록의 실행.
예를 들어
NSLog(@"before dispatch async");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"inside dispatch async block main thread from main thread");
});
NSLog(@"after dispatch async");
인쇄합니다 :
before dispatch async
after dispatch async
inside dispatch async block main thread from main thread
따라서 외부 NSLog 사이에서 블록이 실행될 것으로 예상하면 dispatch_async가 도움이되지 않습니다.
메인 스레드에 있는지 확인할 필요가 없습니다. Swift에서이를 수행하는 방법은 다음과 같습니다.
runThisInMainThread { () -> Void in
runThisInMainThread { () -> Void in
// No problem
}
}
func runThisInMainThread(block: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), block)
}
내 저장소에 표준 기능으로 포함되어 있습니다. https://github.com/goktugyil/EZSwiftExtensions