Eu tenho um retorno de chamada que pode vir de qualquer thread. Quando recebo esse retorno de chamada, gostaria de executar uma determinada tarefa no thread principal.
Preciso verificar se já estou no segmento principal - ou há alguma penalidade por não executar essa verificação antes de chamar o código abaixo?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
Respostas:
Não, você não precisa verificar se você já está no segmento principal. Ao despachar o bloco para a fila principal, você está apenas programando o bloco para ser executado em série no encadeamento principal, o que acontece quando o loop de execução correspondente é executado.
Se você já está no segmento principal, o comportamento é o mesmo: o bloco é agendado e executado quando o loop de execução do segmento principal é executado.
fonte
async
volta para a fila principal, ela será executada, mas isso pode atrapalhar o tempo esperado de suas ações . Tais como o código UI emviewDidLoad()
não correr até após a exibição é exibido pela primeira vez .Para o caso de envio assíncrono descrito acima, não é necessário verificar se você está no thread principal. Como indica Bavarious, isso simplesmente será colocado na fila para ser executado no thread principal.
No entanto, se você tentar fazer o acima usando
dispatch_sync()
ae seu retorno de chamada estiver no thread principal, seu aplicativo entrará em conflito nesse momento. Eu descrevo isso na minha resposta aqui , porque esse comportamento me surpreendeu ao mover algum código de-performSelectorOnMainThread:
. Como mencionei lá, criei uma função auxiliar:que executará um bloco de forma síncrona no segmento principal se o método em que você está atualmente não estiver no segmento principal e apenas executará o bloco em linha, se estiver. Você pode empregar sintaxe como a seguinte para usar isso:
fonte
dispatch_set_specific()
ajudaria no caso de você descrever: stackoverflow.com/a/12806754/19679 .Como as outras respostas mencionadas, o dispatch_async do thread principal está correto.
No entanto, dependendo do seu caso de uso, há um efeito colateral que você pode considerar uma desvantagem: como o bloco está agendado em uma fila, ele não será executado até que o controle volte ao loop de execução, o que atrasará a execução do seu bloco.
Por exemplo,
Irá imprimir:
Por esse motivo, se você esperava que o bloco fosse executado entre os NSLog externos, o dispatch_async não ajudaria.
fonte
Não, você não precisa verificar se está no tópico principal. Aqui está como você pode fazer isso no Swift:
Está incluído como uma função padrão no meu repositório, confira: https://github.com/goktugyil/EZSwiftExtensions
fonte