Quero pausar meu aplicativo em um determinado momento. Em outras palavras, desejo que meu aplicativo execute o código, mas, em um determinado momento, faça uma pausa por 4 segundos e continue com o restante do código. Como posso fazer isso?
Estou usando o Swift.
Respostas:
Em vez de uma suspensão, que bloqueará seu programa se for chamado a partir do thread da interface do usuário, considere usar
NSTimer
ou um cronômetro de despacho.Mas, se você realmente precisar de um atraso no segmento atual:
Isso usa a
sleep
função do UNIX.fonte
Usar um
dispatch_after
bloco é, na maioria dos casos, melhor do que usar,sleep(time)
pois o encadeamento no qual o sono é realizado é impedido de realizar outro trabalho. ao usardispatch_after
o encadeamento em que o trabalho é trabalhado, não é bloqueado, portanto, ele pode realizar outro trabalho nesse meio tempo.Se você estiver trabalhando no segmento principal do seu aplicativo, o uso
sleep(time)
é ruim para a experiência do usuário, pois a interface do usuário não responde durante esse período.Despachar após agendar a execução de um bloco de código em vez de congelar o encadeamento:
Swift ≥ 3,0
Swift <3.0
fonte
.now() + .seconds(4)
dá erro:expression type is ambiguous without more context
.now() + .seconds(5)
é simplesmente.now() + 5
Comparação entre diferentes abordagens no swift 3.0
1. Dormir
Este método não tem uma chamada de retorno. Coloque os códigos diretamente após esta linha para serem executados em 4 segundos. Ele impedirá o usuário de iterar com elementos da interface do usuário, como o botão de teste, até que o tempo se esgote. Embora o botão esteja meio congelado quando o sono entra em ação, outros elementos, como o indicador de atividade, ainda estão girando sem congelar. Você não pode disparar esta ação novamente durante o sono.
2. Despacho, Execução e Temporizador
Esses três métodos funcionam da mesma forma, todos eles estão sendo executados no encadeamento em segundo plano com retornos de chamada, apenas com sintaxe diferente e recursos ligeiramente diferentes.
O despacho é comumente usado para executar algo no encadeamento em segundo plano. Possui o retorno de chamada como parte da chamada de função
Perform é na verdade um timer simplificado. Ele configura um timer com o atraso e, em seguida, aciona a função pelo seletor.
E, finalmente, o timer também oferece a capacidade de repetir o retorno de chamada, o que não é útil nesse caso
Para todos esses três métodos, quando você clicar no botão para acioná-los, a interface do usuário não congelará e você poderá clicar nele novamente. Se você clicar no botão novamente, outro temporizador será configurado e o retorno de chamada será acionado duas vezes.
Em conclusão
Nenhum dos quatro métodos funciona suficientemente bem por si só.
sleep
desativará a interação do usuário, para que a tela " congele " (na verdade) e resulte em uma má experiência do usuário. Os outros três métodos não congelam a tela, mas você pode acioná-los várias vezes e, na maioria das vezes, deseja esperar até receber a chamada antes de permitir que o usuário faça a chamada novamente.Portanto, um design melhor usará um dos três métodos assíncronos com bloqueio de tela. Quando o usuário clicar no botão, cubra a tela inteira com uma exibição translúcida com um indicador de atividade giratória na parte superior, informando ao usuário que o clique do botão está sendo manipulado. Em seguida, remova a visualização e o indicador na função de retorno de chamada, informando ao usuário que a ação foi tratada adequadamente etc.
fonte
@objc
na frente da função de retorno de chamada aperform(...)
opção. Assim:@objc func callback() {
Concordo com Palle que o uso
dispatch_after
é uma boa escolha aqui. Mas você provavelmente não gosta das chamadas do GCD, pois são muito irritantes para escrever . Em vez disso, você pode adicionar este útil auxiliar :Agora você simplesmente adia seu código em um thread de segundo plano como este:
Atrasar o código no thread principal é ainda mais simples:
Se você preferir um Framework que também tenha alguns recursos mais úteis, consulte o HandySwift . Você pode adicioná-lo ao seu projeto via Carthage ou Accio e usá-lo exatamente como nos exemplos acima:
fonte
DispatchTime
não estava disponível no Swift 2. Eralet dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
antes.Você também pode fazer isso com o Swift 3.
Execute a função após um atraso como esse.
fonte
No Swift 4.2 e no Xcode 10.1
Você tem um total de 4 maneiras de adiar. Entre essas opções, é preferível chamar ou executar uma função após algum tempo. O sono () é o menor caso em uso.
Opção 1.
Opção 2.
Opção 3.
Opção 4.
Se você quiser chamar uma função após algum tempo para executar algo, não use sleep .
fonte
NSTimer
A resposta de @nneonneo sugeriu o uso,
NSTimer
mas não mostrou como fazê-lo. Esta é a sintaxe básica:Aqui está um projeto muito simples para mostrar como ele pode ser usado. Quando um botão é pressionado, ele inicia um timer que chamará uma função após um atraso de meio segundo.
Usar
dispatch_time
(como na resposta de Palle ) é outra opção válida. No entanto, é difícil cancelar . ComNSTimer
, para cancelar um evento atrasado antes que aconteça, tudo o que você precisa fazer é ligarO uso
sleep
não é recomendado, especialmente no encadeamento principal, pois interrompe todo o trabalho realizado no encadeamento.Veja aqui a minha resposta mais completa.
fonte
Experimente a seguinte implementação no Swift 3.0
Uso
fonte
Você pode criar extensões para usar a função de atraso facilmente (sintaxe: Swift 4.2+)
Como usar no UIViewController
fonte
Se você precisar definir um atraso menor que um segundo, não será necessário definir o parâmetro .seconds. Espero que isso seja útil para alguém.
fonte
fonte
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {/*Do stuff*/}
é provavelmente mais correto ✌️Se o seu código já estiver sendo executado em um thread em segundo plano, pause o thread usando este método no Foundation :
Thread.sleep(forTimeInterval:)
Por exemplo:
(Veja outras respostas para obter sugestões quando o seu código estiver sendo executado no thread principal.)
fonte
Para criar um atraso de tempo simples, você pode importar o Darwin e usar o modo de suspensão (segundos) para fazer o atraso. Porém, isso leva apenas alguns segundos, portanto, para medições mais precisas, você pode importar o Darwin e usar o uso do sono (milionésimos de segundo) para medições muito precisas. Para testar isso, escrevi:
Que imprime, aguarda 1 segundo e imprime, aguarda 0,4 seg e depois imprime. Tudo funcionou como esperado.
fonte
este é o mais simples
fonte