메인 스레드에서 작업을 수행하기 위한 GCD
어떤 스레드에서든 발생할 수 있는 콜백이 있습니다.이 콜백을 받으면 메인 스레드에서 특정 작업을 수행하고 싶습니다.
내가 이미 메인 스레드에 있는지 확인해야 합니까? 아니면 아래 코드를 호출하기 전에 이 확인을 수행하지 않으면 패널티가 발생합니까?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
아니요, 이미 메인 스레드에 있는지 확인할 필요는 없습니다.블록을 주 대기열에 배치하면 해당 실행 루프가 실행될 때 발생하는 주 스레드에서 연속적으로 실행되도록 블록을 예약할 수 있습니다.
이미 메인 스레드에 있는 경우 동작은 동일합니다. 블록이 예약되고 메인 스레드의 실행 루프가 실행될 때 실행됩니다.
위에서 설명한 비동기식 디스패치의 경우 메인 스레드에 있는지 확인할 필요가 없습니다.바바이어스가 나타내듯이, 이것은 단순히 메인 스레드에서 실행되도록 대기열에 놓입니다.
그러나, 만약 당신이 위의 일을 하려고 한다면,dispatch_sync()
그리고 당신의 콜백은 메인 스레드에 있고, 당신의 애플리케이션은 그 시점에서 교착 상태에 빠질 것입니다.저는 여기 제 대답에 이것을 설명합니다. 왜냐하면 이 행동은 몇몇 코드를 이동할 때 저를 놀라게 했기 때문입니다.-performSelectorOnMainThread:
여기서 언급했듯이 도우미 기능을 만들었습니다.
void runOnMainQueueWithoutDeadlocking(void (^block)(void))
{
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
}
현재 사용 중인 메서드가 메인 스레드에 없는 경우 메인 스레드에서 블록을 동기적으로 실행하고, 있는 경우 인라인으로 블록을 실행합니다.다음과 같은 구문을 사용하여 이를 사용할 수 있습니다.
runOnMainQueueWithoutDeadlocking(^{
//Do stuff
});
다른 답변이 언급했듯이 메인 스레드에서 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
언급URL : https://stackoverflow.com/questions/5662360/gcd-to-perform-task-in-main-thread
'programing' 카테고리의 다른 글
SQL, Postgres OIDs, 그것들은 무엇이고 왜 유용합니까? (0) | 2023.06.01 |
---|---|
로컬 변경 사항이 있더라도 git push에 "모든 것이 최신"으로 표시됩니다. (0) | 2023.06.01 |
서버가 호스트 "localhost"(::1)에서 실행되고 포트 5432에서 TCP/IP 연결을 허용합니까? (0) | 2023.06.01 |
jQuery를 사용하여 다단계 양식 재설정 (0) | 2023.06.01 |
VBA 내에서 Excel에서 시트의 데이터를 새로 고치는 중 (0) | 2023.06.01 |