Entendendo Funções de CallBack

Veja neste artigo como criar e entender as funções de CallBack.

Em várias classes do Delphi existem certos métodos que recebem como parâmetro de entrada uma ação e essa ação será aplicada a elementos internos da classe.

Pode parecer estranho, já que existe um método ele deveria saber o que fazer. Porém o uso de funções de callback pode dar maior flexibilidade quanto à execução do método.

Essa ação que deverá ser passada ao método, é passada em forma de procedimento ou função que deve ser compatível com tipo indicado.

Um exemplo prático da função de callback

Para compreender melhor o que é uma função de callback vamos a um exemplo que organiza uma lista de objetos, para isso vamos usar a classes TList.

A classe TList possui um método que organiza os itens da coleção de objetos armazenados, esse é o método Sort.

Acima mencionamos que alguns métodos podem receber como parâmetro uma ação, no caso do Sort ele requer uma ação de comparação, ou seja, uma função que faça a comparação de seus elementos internos e deve obedecer a seguinte assinatura:

function (Item1: Pointer; Item2: Pointer): integer;

Crie uma classe TClientes como na Listagem 1.

TClientes = class private FNome: string; FEndereco: string; procedure SetNome(const Value: string); procedure SetEndereco(const Value: string); public property Nome: string read FNome write SetNome; property Endereco: string read FEndereco write SetEndereco; end;
Listagem 1. Classe TClientes

Depois, vamos criar as seguintes propriedade e métodos na seção private do formulário principal, Listagem 2.

private { Private declarations } property ListaClientes: TList read FListaClientes write SetListaClientes; procedure EncheListaClientes; procedure AtualizaListBox;
Listagem 2. Seção privada do formulário principal

Na Listagem 3 vemos a implementação deles.

procedure TForm1.EncheListaClientes; begin lCliente1 := TClientes.Create; lCliente1.Nome := "Paulo"; lCliente1.Endereco := "Av. Joao Pereira Barreto"; ListaClientes.Add(lCliente1); lCliente2 := TClientes.Create; lCliente2.Nome := "Andre"; lCliente2.Endereco := "Av. Ayrton Senna"; ListaClientes.Add(lCliente2); lCliente3 := TClientes.Create; lCliente3.Nome := "Jair"; lCliente3.Endereco := "Rua Dom Pedro I"; ListaClientes.Add(lCliente3); end; procedure TForm1.AtualizaListBox; var lIndex: integer; begin ListBox1.Items.Clear; for lIndex := 0 to ListaClientes.Count -1 do ListBox1.Items.Add(TClientes(ListaClientes[lIndex]).Nome + "-" + TClientes(ListaClientes[lIndex]).Endereco); end;
Listagem 3. Implementação

Esta na hora de criar as funções de callback, elas é que vão ditar as regras de comparação/ordenação para o método sort do ListaClientes, veja Listagem 4.

var Form1: TForm1; function ClassificaPorNome(item1: Pointer; item2: Pointer): integer; function ClassificarPorEndereco(item1: Pointer; item2: Pointer): integer; function ClassificaPorNome(item1, item2: Pointer): integer; begin result := CompareText(TClientes(item1).Nome, TClientes(item2).Nome); end; function ClassificarPorEndereco(item1, item2: Pointer): integer; begin result := CompareText(TClientes(item1).Endereco, TClientes(item2).Endereco); end;
Listagem 4. Funções de callback

As funções ClassificaPorNome e ClassificaPorEndereco serão passadas como parâmetro para o método Sort, Listagem 5.

procedure TForm1.Button2Click(Sender: TObject); begin ListaClientes.Sort(@ClassificarPorEndereco); AtualizaListBox; end; procedure TForm1.Button1Click(Sender: TObject); begin ListaClientes.Sort(@ClassificaPorNome); AtualizaListBox; end;
Listagem 5. Utilizando as funções de callback

Observem que não passo o nome da função e sim seu endereço na memória, isso através do operador @. Ao ser chamado, o método Sort localiza a ação a ser tomada, que por sua vez está implementada pela função passada como parâmetro.

Artigos relacionados