Swift – Closures

1 de novembro de 2016   |   by administrador
// Swift - Closures

/*
Definição:
Closures são blocos independentes de funcionalidade que podem ser utilizados em nosso código
São equivalentes aos blocos em Obj-C e lambdas em outras linguagens
A Closure é como se fosse uma função sem nome
Estão sendo muito utilizadas pela Apple para tratar eventos assíncronos nos Apps, como Completion Handlers (blocos de código que são executados quando eventos assíncronos são completados)
Entenda que como uma closure é armazenada separadamente pelo iOS, ele pode ser chamada a qualquer momento pelo sistema operacional, por manter seu estado original.

Declarando uma closure:

Sintaxe mais utilizada:
{ (parameters) -> return type in
statements
}

Se a closure não retornar valor, a "->" pode ser omitida
{ (parameters) in
statements
}

OBS: É mais comum o desenvolvedor utilizar uma closure declarada em classes do iOS do que definir suas próprias closures. Mesmo assim, é muito importante entender como ela funciona.

*/

// Exemplo de uma closure sem parâmetros
let swiftClosure = {
print("Bem-vindos às closures em Swift")
}

// Chamando a closure
swiftClosure()

// Uma closure com dois parâmetros e valor de retorno
let divide = {
(val1: Int, val2: Int) -> Int in
return val1 / val2
}

// Executa a closure
let resultado = divide(200, 20)
print(resultado)

// Várias formas de sintaxe

// 1ª forma - mais completa
let idadeCanina1 = {
(idadeHumana: Int) -> Int in
return idadeHumana + 7
}

// 2ª forma - 1º nível de simplificação
let idadeCanina2 = {
(idadeHumana) in
return idadeHumana + 7
}

// 3ª forma - 2º nível de simplificação
let idadeCanina3 = { return $0 + 7 }

// 4ª forma - exagero total de simplificação
let idadeCanina4 = { $0 + 7 }

// Para receber o retorno das chamadas
var idadeCalculada: Int?

// Chamadas
idadeCalculada = idadeCanina1(10)
idadeCalculada = idadeCanina2(10)
idadeCalculada = idadeCanina3(10)
idadeCalculada = idadeCanina4(10)

// Minha opinião - a melhor forma é a 2, pois fica claro que é uma closure pois aparece a palavra "in"
// Trailing Closures

/*
Quando passamos uma expressão closure para uma função, onde a closure é o último parâmetro, chamamos essa closure de Trailing Closure
A trailing closure pode ser escrita como último parâmetro, antes do parêntesis de fechamento, ou escrita fora (e depois) dos parêntesis da função principal
É a sintaxe utilizada pelos Completion Handlers, utilizados para o tratamento de eventos assíncronos em um App, que podem levar um certo tempo para serem executados antes de retornar os resultados do processamento
--> utilizaremos muito essa sintaxe no curso SDK
*/

// Exemplo
// Declaração de uma função que recebe uma closure como parâmetro
// Como a closure é o último parâmetro, é chamada de Trailing Closure
// A closure contém um parâmetro booleano (Bool) e não tem retorno (Void)
func isTextValid(input: String, completionHandler: (Bool) -> Void) {

// Processamento da Closure
if input == "Instituto de Artes Interativas" {
completionHandler(true)
} else {
completionHandler(false)
}
}

// Chamada da função, passando uma Trailing Closure como último parâmetro
// Observe que a closure está definida entre chaves, no parâmetro Completion Handler
isTextValid(input: "Instituto de Artes Interativas", completionHandler: { (result: Bool) -> Void in

// Processamento após a execução da Closure
if result {
print("Estamos no iai?")
} else {
print("Ops, mas a aula é online")
}
})

// Chamada (simplificada) da função, passando uma Trailing Closure como parâmetro
// O resultado é o mesmo
isTextValid(input: "Instituto de Artes Interativas") { (result) in

// Tratamento de retorno da closure
if result {
print("Estamos no iai?")
} else {
print("Ops, mas a aula é online.")
}

}
Tags: ,