Existe uma maneira de chamar um bloco com um parâmetro primitivo após um atraso, como usar, performSelector:withObject:afterDelay:
mas com um argumento como int
/ double
/ float
?
735
Existe uma maneira de chamar um bloco com um parâmetro primitivo após um atraso, como usar, performSelector:withObject:afterDelay:
mas com um argumento como int
/ double
/ float
?
Respostas:
Eu acho que você está procurando
dispatch_after()
. Ele exige que seu bloco não aceite parâmetros, mas você pode permitir que o bloco capture essas variáveis do seu escopo local.Mais: https://developer.apple.com/documentation/dispatch/1452876-dispatch_after
fonte
dispatch_time(DISPATCH_TIME_NOW, 10ull * NSEC_PER_SEC)
trecho é desagradável. Não existe uma maneira mais limpa para isso?dispatch_get_current_queue()
sempre retorna a fila na qual o código está sendo executado. Portanto, quando esse código for executado no thread principal, o bloco também será executado no thread principal.dispatch_get_current_queue()
está obsoleto agoraVocê pode usar
dispatch_after
para ligar para um bloco mais tarde. No Xcode, comece a digitardispatch_after
e pressioneEnter
para concluir automaticamente o seguinte:Aqui está um exemplo com dois carros alegóricos como "argumentos". Você não precisa confiar em nenhum tipo de macro, e a intenção do código é bastante clara:
Swift 3, Swift 4
Swift 2
Objetivo C
fonte
NSEC_PER_SEC * 0.5
funcionaria da mesma forma queNSEC_PER_MSEC * 500
. Enquanto você está correto ao observar quedispatch_time
espera um número inteiro de 64 bits, o valor esperado é em nanossegundos.NSEC_PER_SEC
é definido como1000000000ull
e multiplicar isso por uma constante de ponto flutuante0.5
implicitamente executaria uma aritmética de ponto flutuante, produzindo500000000.0
, antes que seja explicitamente convertida de volta para um número inteiro de 64 bits. Portanto, é perfeitamente aceitável usar uma fração deNSEC_PER_SEC
.Que tal usar a biblioteca de trechos de código internos do Xcode?
Atualização para Swift:
Muitos votos me inspiraram a atualizar esta resposta.
A biblioteca de trechos de código Xcode incorporada possui
dispatch_after
apenas oobjective-c
idioma. As pessoas também podem criar seu próprio código personalizado de trechos paraSwift
.Escreva isso no Xcode.
Arraste esse código e solte-o na área da biblioteca de trechos de código.
No final da lista de trechos de código, haverá uma nova entidade chamada
My Code Snippet
. Edite isso para um título. Para sugestões ao digitar o Xcode, preencha oCompletion Shortcut
.Para mais informações, consulte CreatingaCustomCodeSnippet .
Atualização Swift 3
Arraste esse código e solte-o na área da biblioteca de trechos de código.
fonte
Expandindo a resposta de Jaime Cham, criei uma categoria NSObject + Blocks como abaixo. Eu senti que esses métodos correspondiam melhor aos
performSelector:
métodos NSObject existentesNSObject + Blocks.h
NSObject + Blocks.m
e use assim:
fonte
delay
deve ser deNSTimeInterval
(que é adouble
).#import <UIKit/UIKit.h>
Não é necessário. E não vejo por que- (void)performBlock:(void (^)())block;
poderia ser útil, portanto pode ser removido do cabeçalho.Talvez seja mais simples do que passar pelo GCD, em uma classe em algum lugar (por exemplo, "Util") ou em uma categoria no objeto:
Então, para usar:
fonte
Para Swift, criei uma função global, nada de especial, usando o
dispatch_after
método Eu gosto mais disso, pois é legível e fácil de usar:Que você pode usar da seguinte maneira:
fonte
after
. Então você pode escrever:after(2.0){ print("do somthing") }
Aqui estão os meus 2 centavos = 5 métodos;)
Eu gosto de encapsular esses detalhes e fazer com que o AppCode me diga como terminar minhas frases.
fonte
PerformSelector: WithObject sempre pega um objeto, portanto, para passar argumentos como int / double / float, etc ..... Você pode usar algo como isto.
// NSNumber é um objeto ..
Da mesma forma que você pode usar [NSNumber numberWithInt:] etc .... e no método de recebimento, você pode converter o número em seu formato como [number int] ou [number double].
fonte
A função dispatch_after despacha um objeto de bloco para uma fila de despacho após um determinado período de tempo. Use o código abaixo para executar algumas tarefas relacionadas à interface do usuário após 2,0 segundos.
No Swift 3.0:
fonte
mainQueue,
vez demainQueue)
Aqui está a maneira do Swift 3 de enfileirar o trabalho após um atraso.
fonte
Aqui está um ajudante útil para evitar fazer a chamada irritante do GCD repetidamente:
Agora você simplesmente adia seu código no thread principal assim:
Se você deseja atrasar seu código para outro segmento :
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 e usá-lo exatamente como nos exemplos acima:
fonte
Há uma boa na estrutura do BlocksKit.
BlocksKit
(e a classe)
BBlocksKit.m
fonte
No swift 3, podemos simplesmente usar a função DispatchQueue.main.asyncAfter para disparar qualquer função ou ação após o atraso de 'n' segundos. Aqui no código, definimos o atraso após 1 segundo. Você chama qualquer função dentro do corpo dessa função que será acionada após o atraso de 1 segundo.
fonte
Xcode 10.2 e Swift 5 e acima
fonte
Você pode agrupar o argumento em sua própria classe ou agrupar a chamada do método em um método que não precise ser passado no tipo primitivo. Em seguida, chame esse método após o seu atraso e, dentro desse método, execute o seletor que deseja executar.
fonte
Aqui está como você pode acionar um bloco após um atraso no Swift:
Está incluído como uma função padrão no meu repositório .
fonte
Swift 3 e Xcode 8.3.2
Este código irá ajudá-lo, eu adiciono uma explicação também
fonte
Acredito que o autor não está perguntando como esperar um tempo fracionário (atraso), mas como passar um escalar como argumento do seletor (withObject :) e a maneira mais rápida no objetivo moderno C é:
seu seletor precisa alterar seu parâmetro para NSNumber e recuperar o valor usando um seletor como floatValue ou doubleValue
fonte