Uma ideia mais clara da estrutura:
dispatch_after(when: dispatch_time_t, queue: dispatch_queue_t, block: dispatch_block_t?)
dispatch_time_té um UInt64. Na dispatch_queue_tverdade, o é um tipo de alias para um NSObject, mas você deve apenas usar seus métodos GCD familiares para obter filas. O bloco é um fechamento Swift. Especificamente, dispatch_block_té definido como () -> Void, que é equivalente a () -> ().
Exemplo de uso:
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
print("test")
}
EDITAR:
Eu recomendo usar dispatch_after - GCD em Swift? .
EDIT 2:
No Swift 3, haverá novos wrappers para GCD. Veja aqui: https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md
O exemplo original seria escrito da seguinte forma no Swift 3:
let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
print("test")
}
Observe que você pode escrever a deadlineTimedeclaração como DispatchTime.now() + 1.0e obter o mesmo resultado porque o +operador é substituído da seguinte maneira (da mesma forma para -):
func +(time: DispatchTime, seconds: Double) -> DispatchTimefunc +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltimeIsso significa que se você não usar o DispatchTimeInterval enume apenas escrever um número, presume-se que você está usando segundos.
Eu uso com dispatch_aftertanta frequência que escrevi uma função de utilitário de nível superior para tornar a sintaxe mais simples:
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
E agora você pode falar assim:
delay(0.4) {
// do stuff
}
Nossa, um idioma onde você pode melhorar o idioma. O que poderia ser melhor?
Quase não vale a pena se preocupar com isso, agora que melhoraram a sintaxe de chamada:
func delay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
Swift 3+
Isso é super fácil e elegante no Swift 3+:
DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
// ...
}
Resposta mais antiga:
Para expandir a resposta de Cezary, que será executada após 1 nanossegundo, eu tive que fazer o seguinte para executar após 4 segundos e meio.
let delay = 4.5 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), block)
Edit: descobri que meu código original estava um pouco errado. A digitação implícita causa um erro de compilação se você não converter NSEC_PER_SEC para um Double.
Se alguém puder sugerir uma solução mais ideal, gostaria muito de ouvi-la.
dispatch_after - GCD em Swift? é muito boa e se você precisar invalidar o bloco, você pode querer usar isto:
typealias dispatch_cancelable_closure = (cancel : Bool) -> Void
func delay(time:NSTimeInterval, closure:()->Void) -> dispatch_cancelable_closure? {
func dispatch_later(clsr:()->Void) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(time * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), clsr)
}
var closure:dispatch_block_t? = closure
var cancelableClosure:dispatch_cancelable_closure?
let delayedClosure:dispatch_cancelable_closure = { cancel in
if closure != nil {
if (cancel == false) {
dispatch_async(dispatch_get_main_queue(), closure!);
}
}
closure = nil
cancelableClosure = nil
}
cancelableClosure = delayedClosure
dispatch_later {
if let delayedClosure = cancelableClosure {
delayedClosure(cancel: false)
}
}
return cancelableClosure;
}
func cancel_delay(closure:dispatch_cancelable_closure?) {
if closure != nil {
closure!(cancel: true)
}
}
Use como segue
let retVal = delay(2.0) {
println("Later")
}
delay(1.0) {
cancel_delay(retVal)
}
O link acima parece estar desativado. Código Objc original do Github
A solução mais simples em Swift 3.0 e Swift 4.0 e Swift 5.0
func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
Uso
delayWithSeconds(1) {
//Do something
}
A Apple tem um snippet dispatch_after para Objective-C :
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
<#code to be executed after a specified delay#>
});
Aqui está o mesmo snippet transferido para o Swift 3:
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + <#delayInSeconds#>) {
<#code to be executed after a specified delay#>
}
Outra maneira é estender Double assim:
extension Double {
var dispatchTime: dispatch_time_t {
get {
return dispatch_time(DISPATCH_TIME_NOW,Int64(self * Double(NSEC_PER_SEC)))
}
}
}
Então você pode usá-lo assim:
dispatch_after(Double(2.0).dispatchTime, dispatch_get_main_queue(), { () -> Void in
self.dismissViewControllerAnimated(true, completion: nil)
})
Eu gosto da função de atraso de matt, mas apenas por preferência, prefiro limitar a passagem de fechamentos.
Em Swift 3.0
Filas de despacho
DispatchQueue(label: "test").async {
//long running Background Task
for obj in 0...1000 {
print("async \(obj)")
}
// UI update in main queue
DispatchQueue.main.async(execute: {
print("UI update on main queue")
})
}
DispatchQueue(label: "m").sync {
//long running Background Task
for obj in 0...1000 {
print("sync \(obj)")
}
// UI update in main queue
DispatchQueue.main.sync(execute: {
print("UI update on main queue")
})
}
Despachar após 5 segundos
DispatchQueue.main.after(when: DispatchTime.now() + 5) {
print("Dispatch after 5 sec")
}
Versão Swift 3.0
A função de fechamento seguinte executa alguma tarefa após o atraso no thread principal.
func performAfterDelay(delay : Double, onCompletion: @escaping() -> Void){
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
onCompletion()
})
}
Chame esta função como:
performAfterDelay(delay: 4.0) {
print("test")
}
1) Adicione este método como parte da extensão UIViewController.
extension UIViewController{
func runAfterDelay(delay: NSTimeInterval, block: dispatch_block_t) {
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue(), block)
}
}
Chame este método no VC:
self.runAfterDelay(5.0, block: {
//Add code to this block
print("run After Delay Success")
})
2)
performSelector("yourMethod Name", withObject: nil, afterDelay: 1)
3)
override func viewWillAppear(animated: Bool) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue(), { () -> () in
//Code Here
})
// Compact Form
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2), dispatch_get_main_queue()) {
//Code here
}
}
Embora não seja a pergunta original do OP, algumas NSTimerperguntas relacionadas foram marcadas como duplicatas desta pergunta, portanto, vale a pena incluir uma NSTimerresposta aqui.
NSTimer vs dispatch_afterNSTimeré de nível mais alto enquanto dispatch_afteré de nível mais baixo.NSTimeré mais fácil de cancelar. O cancelamento dispatch_afterrequer a escrita de mais código .NSTimerCrie uma NSTimerinstância.
var timer = NSTimer()
Inicie o cronômetro com o atraso de que você precisa.
// invalidate the timer if there is any chance that it could have been called before
timer.invalidate()
// delay of 2 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
Adicione uma função a ser chamada após o atraso (usando qualquer nome que você usou para o selectorparâmetro acima).
func delayedAction() {
print("Delayed action has now started."
}
timer.invalidate().repeats: true.Se você tiver um evento único sem necessidade de cancelar, não há necessidade de criar a timervariável de instância. O seguinte será suficiente:
NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
Veja minha resposta completa aqui .
Para múltiplas funções, use isto. Isso é muito útil para usar animações ou carregador de atividades para funções estáticas ou qualquer atualização de IU.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
// Call your function 1
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// Call your function 2
}
}
Por exemplo - use uma animação antes de recarregar uma tableView. Ou qualquer outra atualização da IU após a animação.
*// Start your amination*
self.startAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
*// The animation will execute depending on the delay time*
self.stopAnimation()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
*// Now update your view*
self.fetchData()
self.updateUI()
}
}
No Swift 5, use o seguinte:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: closure)
// time gap, specify unit is second
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
Singleton.shared().printDate()
}
// default time gap is second, you can reduce it
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
// just do it!
}
Isso funcionou para mim.
Swift 3:
let time1 = 8.23
let time2 = 3.42
// Delay 2 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
print("Sum of times: \(time1 + time2)")
}
Objective-C:
CGFloat time1 = 3.49;
CGFloat time2 = 8.13;
// Delay 2 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
CGFloat newTime = time1 + time2;
NSLog(@"New time: %f", newTime);
});
Swift 3 e 4:
Você pode criar uma extensão em DispatchQueue e adicionar atraso de função que usa a função DispatchQueue asyncAfter internamente
extension DispatchQueue {
static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
let timeInterval = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: timeInterval, execute: closure)
}
}
usar:
DispatchQueue.delay(.seconds(1)) {
print("This is after delay")
}
Outro ajudante para atrasar seu código que é 100% Swift em uso e, opcionalmente, permite a escolha de um thread diferente para executar seu código atrasado:
public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
let dispatchTime = DispatchTime.now() + seconds
dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}
public enum DispatchLevel {
case main, userInteractive, userInitiated, utility, background
var dispatchQueue: DispatchQueue {
switch self {
case .main: return DispatchQueue.main
case .userInteractive: return DispatchQueue.global(qos: .userInteractive)
case .userInitiated: return DispatchQueue.global(qos: .userInitiated)
case .utility: return DispatchQueue.global(qos: .utility)
case .background: return DispatchQueue.global(qos: .background)
}
}
}
Agora você simplesmente atrasa seu código no thread principal desta forma:
delay(bySeconds: 1.5) {
// delayed code
}
Se você quiser atrasar seu código para um tópico diferente :
delay(bySeconds: 1.5, dispatchLevel: .background) {
// delayed code that will run on background thread
}
Se você preferir um Framework que também tenha alguns recursos mais úteis, dê uma olhada no HandySwift . Você pode adicioná-lo ao seu projeto via Cartago e usá-lo exatamente como nos exemplos acima, por exemplo:
import HandySwift
delay(bySeconds: 1.5) {
// delayed code
}
Eu sempre prefiro usar extensão em vez de funções livres.
Swift 4
public extension DispatchQueue {
private class func delay(delay: TimeInterval, closure: @escaping () -> Void) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
class func performAction(after seconds: TimeInterval, callBack: @escaping (() -> Void) ) {
DispatchQueue.delay(delay: seconds) {
callBack()
}
}
}
Use como segue.
DispatchQueue.performAction(after: 0.3) {
// Code Here
}
Atrasando chamada GCD usando asyncAfter in swift
let delayQueue = DispatchQueue(label: "com.theappmaker.in", qos: .userInitiated)
let additionalTime: DispatchTimeInterval = .seconds(2)
Podemos atrasar como ** microssegundos , milissegundos , nanossegundos
delayQueue.asyncAfter(deadline: .now() + 0.60) {
print(Date())
}
delayQueue.asyncAfter(deadline: .now() + additionalTime) {
print(Date())
}
Em Swift 4
Use este snippet:
let delayInSec = 1.0
DispatchQueue.main.asyncAfter(deadline: .now() + delayInSec) {
// code here
print("It works")
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// ...
});
A dispatch_after(_:_:_:)função leva três parâmetros:
um atraso,
uma fila de despacho,
um bloqueio ou fechamento
A dispatch_after(_:_:_:)função invoca o bloco ou fechamento na fila de despacho que é passado para a função após um determinado atraso. Observe que o atraso é criado usando a dispatch_time(_:_:)função. Lembre-se disso porque também usamos essa função no Swift.
Eu recomendo seguir o tutorial Raywenderlich Dispatch tutorial
use este código para executar alguma tarefa relacionada à IU após 2,0 segundos.
let delay = 2.0
let delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
let mainQueue = dispatch_get_main_queue()
dispatch_after(delayInNanoSeconds, mainQueue, {
print("Some UI related task after delay")
})
Versão Swift 3.0
A função de fechamento seguinte executa alguma tarefa após o atraso no thread principal.
func performAfterDelay(delay : Double, onCompletion: @escaping() -> Void){
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
onCompletion()
})
}
Chame esta função como:
performAfterDelay(delay: 4.0) {
print("test")
}
Agora, mais do que açúcar sintático para despachos assíncronos no Grand Central Dispatch (GCD) em Swift.
adicionar Podfile
pod 'AsyncSwift'
Então, você pode usá-lo assim.
let seconds = 3.0
Async.main(after: seconds) {
print("Is called after 3 seconds")
}.background(after: 6.0) {
print("At least 3.0 seconds after previous block, and 6.0 after Async code is called")
}
O Swift 4 tem uma maneira bastante curta de fazer isso:
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (timer) in
// Your stuff here
print("hello")
}
Aqui está a versão síncrona de asyncAfter em Swift:
let deadline = DispatchTime.now() + .seconds(3)
let semaphore = DispatchSemaphore.init(value: 0)
DispatchQueue.global().asyncAfter(deadline: deadline) {
dispatchPrecondition(condition: .onQueue(DispatchQueue.global()))
semaphore.signal()
}
semaphore.wait()
Junto com o assíncrono:
let deadline = DispatchTime.now() + .seconds(3)
DispatchQueue.main.asyncAfter(deadline: deadline) {
dispatchPrecondition(condition: .onQueue(DispatchQueue.global()))
}
Jana Duggar foi aberta sobre sua busca pelo amor. Aqui está tudo o que ela disse sobre o assunto e sua janela de cinco anos para o casamento.
O astro de 'Outlander', Sam Heughan, revelou recentemente o que vai levar do set para relembrar Jamie Fraser, o papel que o tornou uma estrela.
'She Loves You' foi escrita em uma hora, gravada em um dia, e foi a música dos Beatles com uma de suas melhores apresentações de sua carreira.
Dolly Parton e sua avó Bessie tiveram um relacionamento especial. Vovó Parton estava muito doente, mas isso não impediu Dolly de pregar uma peça nela.
Você pode achar que o carvalho ou a nogueira são madeiras resistentes, mas quando se trata da madeira mais dura do mundo, elas nem chegam perto.
O oceano é repleto de beleza, mas também esconde algumas das criaturas marinhas mais assustadoras do planeta. Muitos desses animais espreitam nas profundezas do oceano, no mundo escuro e de alta pressão do fundo do mar.
Se você está enfrentando criaturas hostis ou se preparando para cenários PvP, conhecer os melhores encantamentos de espada no Minecraft pode te dar uma grande vantagem. Encantar espadas permite causar mais dano, aumentar a quantidade de itens obtidos de criaturas e prolongar a durabilidade da sua espada.
Quando as pessoas falam sobre países socialistas, geralmente imaginam o controle total do governo e a ausência de propriedade privada. Mas, na prática, as economias socialistas variam muito.
“Children” traz uma participação especial de grande nome e algumas notícias devastadoras
Este RAV4 está em excelentes condições e está preparado para um jogo de cadeiras musicais.
Imagens de drone capturaram bombeiros parecendo lutar para apagar o incêndio.
Eyes of Wakanda está diretamente relacionado ao MCU, além de atualizações sobre X-Men '97, What If..., Demolidor e muito mais.
O anel de noivado de Kate Middleton pertenceu à Princesa Diana antes do Príncipe William pedi-la em casamento. Descubra tudo o que há para saber sobre a peça histórica aqui.
John Cleese se casou com sua esposa, Jennifer Wade, em 2012. Aqui está tudo o que você precisa saber sobre a esposa de John Cleese, Jennifer Wade.
Patton Oswalt se casou com sua esposa, a também atriz Meredith Salenger, em 2017. Aqui está tudo o que você precisa saber sobre a esposa de Patton Oswalt, Meredith Salenger.
Mena Suvari é casada com o marido Michael Hope desde 2018. Aqui está tudo o que você precisa saber sobre o marido de Mena Suvari.
Isso me atinge De repente, como tantas vezes acontece É o meio do caminho tudo de novo <Não, não aquele no Pacífico, seu marrom, aquele no carnaval> Todas as manchetes em voz alta…..
Em 2022, com o lançamento do GPT-3, a habilidade de escrita parece se tornar menos importante. Com a IA, pessoas com redação ruim também podem gerar funcionários de qualidade.
No mundo acelerado e competitivo de hoje, a carreira desempenha um papel significativo no crescimento pessoal, na estabilidade financeira e na satisfação geral com a vida. No entanto, muitos indivíduos encontram-se presos em um ciclo implacável de estagnação e insatisfação, definhando gradualmente em suas vidas profissionais.
Na semana passada, notei um comunicado de imprensa, enviado via PressGazette (um site de notícias da mídia britânica). O artigo anunciava que a Acast, a empresa de publicidade e hospedagem de podcast Scandi, lideraria um consórcio de "provavelmente os editores mais influentes" em podcasting.