Considerando um tema muito importante para se abordar quando falamos em programação em swift. Hoje vamos falar de tuples, protocolos e delegates.
Tuples
Como fazemos se queremos que uma função retorne dois valores? Temos três opções até agora. Devolvemos um array, um dicionário ou um objecto.
Em swift existe outra possibilidade. Os tuples.
A criação de um tuple assemelha-se a outra variável ou constante, mas adiciona outro valor em que agrupamos num tuple dois valores. Esse tuple pode ter um tipo explicito ou dinâmico, como explicamos no artigo sobre variáveis.
//Tuple dinâmico let linguagens = ("objective-c","swift") //Tuple de declaração implicita let linguagens:(String,String) = ("objective-c","swift")
Os tuples podem ser acedidos como se de um array com dois elementos se tratasse, com uma modificação ligeira na sintaxe.
//Primeiro elemento - objective-c println(linguagens.0) //Segundo elemento - swift println(linguagens.1)
Podem tambem ser acedidos de uma maneira mais elegante. Por nome. Neste caso, cada elemento do tuple terá um nome.
let (primeira,segunda) = linguagens //Imprime objective-c println(antes) //Imprime swift println(depois)
Apesar do funcionar, o código anterior não é muito elegante. O método mais conveniente de utilização de tuples, são os tuples com nome.
Ao utilizar tuples com nome, aquando da sua declaração, damos um nome a cada elemento. No exemplo seguinte são ilustradas as duas maneiras possíveis. Com tipo implícito e dinâmico.
//Tuple dinâmico let linguagens2 = (primeira:"objective-c", segunda:"swift") //Tuple implicito let linguagens:(primeira:String,segunda:String) = ("objective-c", "swift")
Para retornar um tuple só temos de incluir os valores no retorno.
func exemploTuple() ->(primeira:String, segunda:String){ return ("objective-c","swift") }
Protocolos
Um protocolo serve para obrigar uma classe, por exemplo, que o estenda a implementar os métodos nele definidos.
No protocolo somente se definem os métodos e não é feita qualquer implementação desse. São métodos vazios, abstractos.
O protocolo pode ser adoptado por uma classe, estrutura de dados ou enumerador. No exemplo seguinte é demonstrada a adopção de um protocolo por uma classe.
protocol programacao{ func linguagem() func ano() func facilidade() } class estendeProtocolo: programacao{ func linguagem() { } func ano() { } func facilidade() { } }
A classe poderia estender vários protocolos. Nesse caso cada protocolo seria separado por uma virgula (,). Caso não implementemos todos os métodos do protocolo na classe que dele estende, o IDE dá um erro que acusa a classe de não se conformar com o protocolo’x’.
O problema até agora, é o facto de por vezes ser preciso que determinada classe adopte um protocolo, mas existe um método que não interessa. Nesse caso, utilizamos métodos opcionais no protocolo.
@objc protocol programacao{ func linguagem() func ano() optional func facilidade() } class estendeProtocolo: programacao{ func linguagem() { } func ano() { }
Delegates
Embora não dê nenhum exemplo em concreto, quero dar uma introdução aos delegates.
Um delegate é uma classe normal. É uma forma de passar dados de um objecto para outro. Podemos pensar nos delegates como callbacks, que são chamados quando acontece determinada acção. Por exemplo, em javascript os eventos onClick(). Em swift esses eventos seriam chamados de delegates.
Por exemplo, quando implementamos uma tabela na nossa aplicação e queremos aceder ao elemento que está seleccionado, temos de extender a classe do delegate da tableView. Esse delegate, obriga a implementação de alguns métodos de configuração da tabela e tem outros opcionais. Um deles serve para aceder ao item da célula seleccionada.
Para sintetizar:
- Extender o delegate;
- Indicar que a nossa classe delega do delegate estendido;
- Implementar os métodos obrigatórios do delegate e os que quisermos da documentação da classe que estamos a delegar;