Documentação: http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Classes.TComponent.FreeNotification e http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Classes.TComponent.Notification
Existem alguns casos onde um componente precisa saber quando outro componente foi destruído. Isso ocorre principalmente na construção de componentes, mas pode ser utilizados em qualquer outro caso em que a lógica se aplique.
Utilizamos o método FreeNotification para realizar a essa tarefa de forma muito simples no Delphi.
Basicamente, FreeNotification registra o componente em uma lista que será disparada no momento de sua destruição, alertando todos os outros componentes alí registrados que ele foi destruído.
Como exemplo, vamos criar a classe TTeste abaixo:
1 2 3 4 5 |
type TTeste = class(TComponent) protected procedure Notification(AComponent: TComponent; Operation: TOperation); override; end; |
TTeste é uma classe que herda de TComponent e reimplementa o método virtual Notification:
1 2 3 4 5 6 |
procedure TTeste.Notification(AComponent: TComponent; Operation: TOperation); begin inherited Notification(AComponent, Operation); ShowMessage('Foi destruído e fui notificado!'); end; |
Depois disso, vamos olhar o código abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
procedure TForm2.EventoTeste(Sender: TObject); var Teste: TTeste; Shape: TShape; begin Teste := TTeste.Create(nil); Shape := TShape.Create(nil); //Adiciona o componente Teste para ser notificado quando Shape for destruído. Shape.FreeNotification(Teste); //Destrói o shape e aciona consequentemente a notificação para Teste de sua destruição Shape.Free; Teste.Free; end; |
O que foi feito aqui em cima foi adicionar Teste (TTeste) na lista de componentes a serem notificados quando Shape for destruído. No momento que chamamos Shape.Free, o método Notification de TTeste é executado. Assim, TTeste pode tratar como cuidará dessa informação.
Isso geralmente é utilizado quando existem referências em um objeto de outro objeto. Comumente vemos essa situação em componentes que referenciam popups menus ou datasets. Assim, caso o popup menu ou o dataset seja destruído, é possível alterar a referência para nil, evitando apontar para um endereço de memória que não mais está utilizável.
Esse tratamento não é necessário quando o componente está no mesmo form (dependendo da lógica) ou quando ambos componentes possuem o mesmo owner. Isso devido a forma como o Delphi trabalha com a memória. Componentes do mesmo form são destruídos na destruição do form e componentes que possuem o mesmo dono (owner) são destruídos na destruíção do owner. Além disso, Notification não é executado na destruição do owner, porque trata-se de uma liberação natural da memória, e um evento esperado.
Tem outra ideia onde isso possa ajudar no desenvolvimento de aplicações? Compartilhe conosco seus pensamentos.