Métodos para Operações com Atraso em iOS
Em desenvolvimento iOS, agendar tarefas com atraso é essencial para melhorar a experiência do usuário e gerenciar fluxos assíncronos. Diversas abordagens estão disponíveis, incluindo performSelector, dispatch_after e NSTimer. Cada técnica possui implicações de segurança, flexibiliddae e integração com o RunLoop.
Usando dispatch_after para Atraso Seguro
O dispatch_after, parte do Grand Central Dispatch (GCD), oferece uma maneira segura de executar um bloco de código após um intervalo específico. É recomendado para cenários que exigem confiabilidade, como atualizações de interface do usuário.
// Configuração de um atraso de 3 segundos
dispatch_time_t tempoAtraso = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC);
dispatch_after(tempoAtraso, dispatch_get_main_queue(), ^{
[self removerElementoDaTela];
});
- (void)removerElementoDaTela {
NSLog(@"Elemento removido após 3 segundos");
[self.bannerView removeFromSuperview];
}
Utilização do performSelector com Diferentes Variantes
O método performSelector é frequentemente usado para invocar métodos de forma dinâmica, mas seu uso para atrasos pode apresentar riscos, como retenção de memória. O modo padrão é NSDefaultRunLoopMode, que depende do ciclo de eventos do RunLoop.
// Chamada direta de um método
[self performSelector:@selector(ocultarConteudo)];
// Passagem de parâmetros
NSString *mensagem = @"Exemplo de texto";
[self performSelector:@selector(exibirMensagem:) withObject:mensagem];
// Atraso na execução com parâmetro
[self performSelector:@selector(exibirMensagem:) withObject:mensagem afterDelay:2.0];
// Execução na thread principal com controle de espera
[self performSelectorOnMainThread:@selector(exibirMensagem:) withObject:mensagem waitUntilDone:NO];
- (void)ocultarConteudo {
NSLog(@"Conteúdo ocultado");
[self.conteudoView setHidden:YES];
}
- (void)exibirMensagem:(NSString *)texto {
NSLog(@"Mensagem: %@", texto);
[self.rotulo setText:texto];
}
Implementação com NSTimer para Atrasos Recorrrentes ou Únicos
O NSTimer permite criar temporizadores que podem ser configurados para disparar uma vez ou repetidamente. Ele se integra ao RunLoop e oferece métodos para iniciar, pausar ou cancelar a execução.
// Inicialização com atraso único
NSTimer *temporizador = [NSTimer scheduledTimerWithTimeInterval:4.0
target:self
selector:@selector(atualizarDados)
userInfo:nil
repeats:NO];
// Alternativa: criação manual e adição ao RunLoop
NSTimer *temporizadorManual = [NSTimer timerWithTimeInterval:4.0
target:self
selector:@selector(atualizarDados)
userInfo:nil
repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:temporizadorManual forMode:NSDefaultRunLoopMode];
- (void)atualizarDados {
NSLog(@"Dados atualizados após 4 segundos");
[self.carregarDados];
}
// Para disparar imediatamente: [temporizador fire];
// Para interromper: [temporizador invalidate];
O performSelector com afterDelay: usa o RunLoop, o que pode levar a bloqueios se a thread estiver ocupada. Em contraste, dispatch_after é baseado em filas do GCD e é mais eficiente para tarefas assíncronas. O NSTimer é útil quando há necessidade de controle fino sobre o ciclo de vida do temporizador.