Method Dispatch no Swift
Tags: ios, português, swift
Published: 2020-05-11 17:33:31

---
title: Method Dispatch no Swift
published: true
date: 2020-05-11 16:39:16 UTC
tags: ios,português,swift
canonical_url: 
---

> Method Dispatch refere-se ao mecanismo que determina qual implementação deve ser utilizada quando um método é chamado.

Conhecer como o _dispatch_ trabalha é necessário para escrever código performático e pode ajudar a entender alguns comportamentos confusos do  **Swift**.

### Static Dispatch

_Static Dispatch,_ ou _Direct Dispatch,_ é suportado tanto por **tipos de valor** quanto por **tipos de referência**.

Se um método é despachado estaticamente, o compilador pode localizar onde as instruções estão em **tempo de compilação** , sendo assim quando a função é chamada o sistema vai diretamente ao endereço de memória onde a função está armazenada para realizar a operação.

Esse comportamento resulta em uma execução muito rápida e permite que o compilador realize vários tipos de otimizações (_devirtualization_).

#### Exemplos

![](https://cdn-images-1.medium.com/max/924/1*ROE5vuMlWEjIpVBgpGBdnQ.png)<figcaption>Exemplo de dispatch com struct</figcaption>

`Struct` e `enum` são tipo de valores que não suportam herança, portanto todos os métodos são do tipo _static_.

![](https://cdn-images-1.medium.com/max/924/1*2wMsZisJ7cKXQr_dr59BZA.png)<figcaption>Exemplo de dispatch com protocol</figcaption>

Métodos que não são definidos no contrato de um protocolo mas fazem parte da sua extensão são do tipo estático.

### Dynamic Dispatch

É suportado somente por tipos de referência, ou classes, já que são tipos que suportam herança.

Apesar de _static dispatch_ ser leve e rápido é limitado. Devido principalmente ao polimorfismo, uma grande quantidade de linguagens OOP suportam o _dynamic dispatch_.

Em Swift existem duas formas de _dynamic dispatch_:

#### Table dispatch

Com esse método uma classe é associada a uma tabela virtual que consiste de um array de ponteiros para a implementação real correspondente para a classe.

Cada classe possui sua cópia da tabela com ponteiros para cada método que foi feito o `override`. Assim a cada chamada a um método o compilador precisa verificar, em **tempo de execução,** as implementações desse método em uma tabela virtual (_witness table_) e determinar se a chamada se refere a implementação da _superclass_ ou da _subclass_.

Como o compilador precisar ler o endereço de memória da implementação e pular para esse endereço correspondente, o d_ynamic dispatch_ é um pouco mais lento que o _static dispatch_.

#### Message dispatch

Esse é um tipo de _dispatch_ fornecido pelo **Objective-C** e o Swift usa a _runtime lib_ do Objective-C para fazer a procura pela implementação correta.

Diferente do tabela virtual do _table dispatch_ o dicionário de mensagens pode ser alterado em **tempo de execução** , o que possibilita alterar a funcionalidade de um método (_method swizzling_). Isso pode ser custoso, apesar de usar um mecanismo de cache, já que quando um método é chamado o _runtime_ do Objective-C precisa passar pela hierarquia de classes para determinar qual implementação do método chamar.

O _message dispatch_ é muito usado nos frameworks **Cocoa** , como [**KVO**](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html) **,** [**Core Data**](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/index.html) e [**UIAppearance**](https://developer.apple.com/documentation/uikit/uiappearance) **.** Caso queira saber mais esse [post](http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/) apresenta vários detalhes técnicos.

#### Exemplos

![](https://cdn-images-1.medium.com/max/1024/1*s3OKbthQJDvn4qrDcF5wrQ.png)<figcaption>Exemplos de dispatch em uma classe</figcaption>

A partir do Swift 4.0 precisamos marcar explicitamente que queremos expor nosso método para o Objective-C _runtime_.

![](https://cdn-images-1.medium.com/max/924/1*N_FOZjGUiKSRkY5Kr_ZqZA.png)<figcaption>Exemplo de static dispatch em classe com ”<em>final"</em></figcaption>

Quando uma classe não terá subclasses podemos marcar ela como final, isso faz com que seus métodos usem o _static dispatch_.

![](https://cdn-images-1.medium.com/max/591/1*Bwndx_OV_AJdZzaehkODkg.jpeg)<figcaption>Resumo</figcaption>

Bom, é isso!

A ideia desse artigo era falar um pouco sobre um assunto mais técnico em português, já que a grande maioria do material encontrado é em inglês.

Espero que o artigo tenha sido útil e qualquer crítica, sugestão ou melhoria é só comentar.

Caso queira ler os artigos originais em que esse texto foi baseado são:  
- [https://trinhngocthuyen.github.io/tech/method-dispatch-in-swift/](https://trinhngocthuyen.github.io/tech/method-dispatch-in-swift/)  
- [https://medium.com/flawless-app-stories/static-vs-dynamic-dispatch-in-swift-a-decisive-choice-cece1e872d](https://medium.com/flawless-app-stories/static-vs-dynamic-dispatch-in-swift-a-decisive-choice-cece1e872d)  
- [https://www.rightpoint.com/rplabs/switch-method-dispatch-table](https://www.rightpoint.com/rplabs/switch-method-dispatch-table)