Olá, hoje vou postar um artigo (antigo) do blog do Erick Sasse explicando a diferença entre os comandos Free, FreeAndNil e Release no Delphi.
Se vc não sabe a diferença, vale a pena conferir. Abaixo o post na íntegra:
Durante minha palestra sobre OO no ClubeDelphi TW várias pessoas me perguntaram sobre a diferença entre Free, FreeAndNil e Release. Como eu não sabia, pois sempre usei Free e nunca tive problemas, fiquei de pesquisar e comentar o que encontrasse. Portanto aqui estão meus comentários a respeito:
O Release só serve para forms, pois é introduzido na classe TCustomForm. Ele deve ser usado se você quer liberar um form de dentro dele mesmo, por exemplo, no evento OnClick de um botão no próprio form. O Release posta uma mensagem CM_RELEASE para o form (veja TCustomForm.Release na unit Forms), que quando processada, dispara o Free. A diferença é que o Release processa todas as mensagens e eventos que estiverem na fila do form antes que ele seja destruido. Disparar um Free de dentro do form, pode gerar um AV.
O Free deve ser usado quando você quer libera o form fora do contexto do form, por exemplo, isto está correto:
Form := TForm1.Create(Application); Form.ShowModal; Form.Free;Usar o Release de fora do form também gera o mesmo resultado, porém de forma menos otimizada, pois a mensagem é postada para o form que depois chama o Free.
Form := TForm1.Create(Application); Form.ShowModal; Form.Release;O FreeAndNil é apenas uma procedure que atribui nil a variável de instância e na sequência chama um Free, conforme se pode ver no seu código ultra-simples em SysUtils:
procedure FreeAndNil(var Obj); var Temp: TObject; begin Temp := TObject(Obj); Pointer(Obj) := nil; Temp.Free; end;Ele só é interessante de ser usado quando você precisa testar se o objeto está instanciado usando o Assigned. Se você chama apenas o Free a memória é liberada da mesma forma, sem vestígios, porém, se a variável não for reutilizada e ainda estiver dentro do escopo, continuará apontando para um endereço inválido. Isso não consome mais memória, e isso não é um problema se você não precisa mais da variável. Por isso aconselho sempre a usar variáveis com o menor escopo possível, pois dessa forma, você quase nunca precisa se preocupar com esse tipo de problema.
Exemplo 1: Variável implicita:
procedure TForm1.Button5Click(Sender: TObject); begin with TForm2.Create(nil) do try ShowModal; finally Free; end; end;Neste caso você nem precisa se preocupar com variável nenhuma. Sei que muita gente odeia o with, mas em pequenos trechos como esse, não vejo desvantagens, e ele ainda me economiza a declaração da variável para o form. Não preciso usar Release pois estou liberando o form fora dele, e não preciso do FreeAndNil porque em nenhum momento preciso testar variável nenhuma para saber se existe uma instância.
Exemplo 2: Variável local:
procedure TForm1.Button4Click(Sender: TObject); var Form: TForm2; begin Form := TForm2.Create(Application); Form.ShowModal; Form.Free; end;O resultado é o mesmo do exemplo 1, porém usando uma variável local. Não precisamos do Release pelo mesmo motivo do anterior e não precisamos do FreeAndNil, pois ao final da procedure, a variável Form sai do escopo e morre. Não precisamos nos preocupar em atribuir nil a ela.
Exemplo 3: Form não destruido ao fechar
type TMeuForm = class(TForm) public class procedure Mostrar; end; implementation var Form: TMeuForm; {$R *.dfm} { TForm2 } class procedure TMeuForm.Mostrar; begin if not Assigned(Form) then Form := TMeuForm.Create(Application); Form.Show; end;Se você precisa que um form fique na memória, pode usar este código acima. Ao ser chamado pela primeira vez, o Mostrar testa para ver se o form já está criado, Se não estiver ele cria e mostra, se já estiver criado, ele apenas mostra. Este form tem como owner o aplicativo, portanto ao finalizar seu aplicativo, o form será finalizado juntamente e você não precisa se preocupar com mais nada.
Exemplo 4: Form sem variável
Um form sem variável pode ser facilmente mostrado assim:
TMeuForm.Create(Application).Show;ou assim:
TMeuForm.Create(Application).ShowModal;E no OnClose do form, basta colocar:
procedure TMeuForm.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end;Com isso o form é liberado assim que for fechado.
Enfim, esses quatro exemplos atendem todas as minhas necessidades sem usar Release nem FreeAndNil. Felizmente eu já estava no caminho certo.
Fonte: www.ericksasse.com.br/free-vs-freeandnil-vs-release
Até o próximo post…
Sempre usei o release e nunca obtive problemas…
Achei o post muito interessante.