Você está na página 1de 7

23/01/2016 Free vs. FreeAndNil vs.

 Release

Erick Sasse Sobre  TPodcast

Free vs. FreeAndNil vs. Release
Jul 20, 2005 • Erick Sasse • editar

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:

ʳ…‘†‡ʴ ‘”śʰ ‘”ɨŜ”‡ƒ–‡ſ’’Ž‹…ƒ–‹‘ƀŚ


‘”ŜŠ‘™‘†ƒŽŚ
‘”Ŝ ”‡‡Śʳŵ…‘†‡ʴ

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.

ʳ…‘†‡ʴ ‘”śʰ ‘”ɨŜ”‡ƒ–‡ſ’’Ž‹…ƒ–‹‘ƀŚ


‘”ŜŠ‘™‘†ƒŽŚ
‘”Ŝ‡Ž‡ƒ•‡Śʳŵ…‘†‡ʴ

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:

ʳ…‘†‡ʴ’”‘…‡†—”‡ ”‡‡†‹Žſ˜ƒ”„ŒƀŚ

http://ericksasse.com.br/free­vs­freeandnil­vs­release/ 1/7
23/01/2016 Free vs. FreeAndNil vs. Release

˜ƒ”
‡’ś„Œ‡…–Ś
„‡‰‹
‡’śʰ„Œ‡…–ſ„ŒƀŚ
‘‹–‡”ſ„Œƀśʰ‹ŽŚ
‡’Ŝ ”‡‡Ś
‡†Śʳŵ…‘†‡ʴ

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:

ʳ…‘†‡ʴ’”‘…‡†—”‡ ‘”ɨŜ—––‘ɬŽ‹…ſ‡†‡”ś„Œ‡…–ƀŚ
„‡‰‹
™‹–Š ‘”ɩŜ”‡ƒ–‡ſ‹Žƀ†‘
–”›
Š‘™‘†ƒŽŚ
ˆ‹ƒŽŽ›
 ”‡‡Ś
‡†Ś
‡†Śʳŵ…‘†‡ʴ

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:

ʳ…‘†‡ʴ’”‘…‡†—”‡ ‘”ɨŜ—––‘ɫŽ‹…ſ‡†‡”ś„Œ‡…–ƀŚ
˜ƒ”
 ‘”ś ‘”ɩŚ

http://ericksasse.com.br/free­vs­freeandnil­vs­release/ 2/7
23/01/2016 Free vs. FreeAndNil vs. Release

„‡‰‹
 ‘”śʰ ‘”ɩŜ”‡ƒ–‡ſ’’Ž‹…ƒ–‹‘ƀŚ
 ‘”ŜŠ‘™‘†ƒŽŚ
 ‘”Ŝ ”‡‡Ś
‡†Śʳŵ…‘†‡ʴ

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

ʳ…‘†‡ʴ–›’‡
‡— ‘”ʰ…Žƒ••ſ ‘”ƀ
’—„Ž‹…
…Žƒ••’”‘…‡†—”‡‘•–”ƒ”Ś
‡†Ś

‹’Ž‡‡–ƒ–‹‘

˜ƒ”
 ‘”ś‡— ‘”Ś

ƇɛƋŜ†ˆƈ

Ƈ ‘”ɩƈ

…Žƒ••’”‘…‡†—”‡‡— ‘”Ŝ‘•–”ƒ”Ś
„‡‰‹
‹ˆ‘–••‹‰‡†ſ ‘”ƀ–Š‡
 ‘”śʰ‡— ‘”Ŝ”‡ƒ–‡ſ’’Ž‹…ƒ–‹‘ƀŚ
 ‘”ŜŠ‘™Ś
‡†Ś
ʳŵ…‘†‡ʴ

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.

http://ericksasse.com.br/free­vs­freeandnil­vs­release/ 3/7
23/01/2016 Free vs. FreeAndNil vs. Release

Exemplo 4: Form sem variável

Um form sem variável pode ser facilmente mostrado assim:

ʳ…‘†‡ʴ‡— ‘”Ŝ”‡ƒ–‡ſ’’Ž‹…ƒ–‹‘ƀŜŠ‘™Śʳŵ…‘†‡ʴ

ou assim:

ʳ…‘†‡ʴ‡— ‘”Ŝ”‡ƒ–‡ſ’’Ž‹…ƒ–‹‘ƀŜŠ‘™‘†ƒŽŚʳŵ…‘†‡ʴ

E no OnClose do form, basta colocar:

ʳ…‘†‡ʴ’”‘…‡†—”‡‡— ‘”Ŝ ‘”Ž‘•‡ſ‡†‡”ś„Œ‡…–Ś˜ƒ”…–‹‘śŽ‘•‡…–‹‘ƀŚ


„‡‰‹
…–‹‘śʰ…ƒ ”‡‡Ś
‡†Śʳŵ…‘†‡ʴ

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.

8 Comentários Erick Sasse Blog 
1  Entrar

  Recommend ⤤ Compartilhar Ordenar por Melhor avaliado

Participe da discussão...

Douglas Cunha  •  10 anos atrás
Muito interessante, porém gostaria de fazer uma resalva. No exemplo abaixo não
vejo motivo para passar o Owner, pois você vai ser o responsável por destruir o
objeto e não o Owner. Dê uma olhada no construtor de TComponent e veja o que
acontece se passamos o Owner nil e entenderá o desperdício. Use assim:

with TForm2.Create(nil) do
try
ShowModal;
finally
Free;
end;

Eu costumo sempre passar o Owner como nil se eu for destruir o objeto
http://ericksasse.com.br/free­vs­freeandnil­vs­release/ 4/7
23/01/2016 Free vs. FreeAndNil vs. Release
Eu costumo sempre passar o Owner como nil se eu for destruir o objeto
manualmente, evitando um possível AV se por exemplo eu der um Free em
finalization de uma unit. Se você instancia um objeto com Owner Application em
Initialization por exemplo, e libera com free em finalization, tera um AV, pois o
Application terá liberado a instância do objeto antes de seu free.
Abraço.
1 △   ▽ • Responder • Compartilhar › 

jose soares  •  5 anos atrás
Olah erick,
tenho um caso que estah me tirando o sono. um sistema onde os forms de
manutencoes sao dinamicos, isso eh, o mesmo form para dah manutencao em
diversas tabelas. e nesses forms tem campos que chamam uma tela de consulta. na
tela de consulta tem um botao (incluir) para no caso que a consulta nao for satisfeita
o usuario dali mesmo ja poder buscar a tela de cadastro e incluir o que for
necessario. podendo abrir varias telas sucessivamente.
Com apenas uma tela aberta apos a consulta (botao incluir), apos o retorno para o
form origem nao dah erro. mas quando o usuario abre varias telas atravez das
consultas ai no retorno do form origem dah erro.
Minha pergunta: Que vc me indicaria para melhor gerenciar esse problema???
△  ▽ • Responder • Compartilhar › 

Erick Sasse  Mod   > jose soares  •  5 anos atrás


Dificil entender sem ver código. Se quiser me mandar um pequeno projeto
que reproduz esse cenário por e­mail, posso dar uma olhada.
△  ▽ • Responder • Compartilhar › 

Rodrigo  •  7 anos atrás
Olá Erik.

Gostaria de lhe perguntar se você sabe qual a maneira mais correta de liberar
memória de objetos alocados usando o Delphi for .net? Pergunto isto porque tenho
algumas DLLs feitas em delphi .net, que são chamadas apartir de aplicações win32
feitas em delphi, e estou tendo dificuldades para liberar memória de objetos que
usam certificado digital e arquivos XML. Como no Delphi .net não tem a função
FreeAndNil eu estou usando o Free e logo em seguida passando nil para o objeto,
mas não esta resolvendo, pois depois que termina a execução da dll a memória
continua alocada em memória! Se puder ajudar ficarei grato.
△  ▽ • Responder • Compartilhar › 

Daniel Breda  •  9 anos atrás
Eu sempre uso FreeAndNil(); pois se eu precisar checar se a variável está
instânciada sempre vou ter o resultado correto assim padronizando de forma clara e
sem POG meu codigo, claro que cada caso é um caso, no meu esta foi a melhor
forma que encontrei.
△  ▽ • Responder • Compartilhar › 

http://ericksasse.com.br/free­vs­freeandnil­vs­release/ 5/7
23/01/2016 Free vs. FreeAndNil vs. Release

Erick Sasse  Mod   •  9 anos atrás


Aldo, a melhor forma de tirar essa dúvida é olhar o código da VCL. Quando um
TDataSet é destruído, ele chama o Close automaticamente, então não é necessário
que você chame. Pode destruir diretamente.
△  ▽ • Responder • Compartilhar › 

Aldo Leonardo  •  9 anos atrás
Olá Erick,
Estou com uma duvida cruel,
Uso bastante query dinamica e gostaria de saber se quando eu dou um
freeandnil(query) o banco ao qual essa query estava conectada continua registrando
a sua conexão ou quando destruo essa query a conexão é automaticamente
fechada?????????

Então,,

Eu posso fazer simplesmente freeandnil(query)

Ou devo sempre fazer:
query.close;
freeandnil(query);
????????????????????????
△  ▽ • Responder • Compartilhar › 

Erick Sasse  •  10 anos atrás
Você está certíssimo, eu já não passo mais o owner quando destruo manualmente o
componente. Só me toquei disso algum tempo depois de escrever este artigo, e
acabei me esquecendo de atualizar aqui.

Inclusive publiquei um post aqui sobre isso, veja:
http://www.ericksasse.com.br/?...

Estou corrigindo o artigo, obrigado pelo toque.
△  ▽ • Responder • Compartilhar › 

TAMBÉM EM ERICK SASSE BLOG O QUE É ISSO?

TPodcast 4 – Novidades do Delphi Review Controle Universal Logitech
XE2 Harmony One
32 comentários • 4 anos atrás 7 comentários • 5 anos atrás
Popoca — Talvez seja tarde e você já Erick Sasse — Não tem marca, é bem
tenha descoberto que o PDF do genérico mesmo.
Fastreport funciona no Linux. Quando
comprei o XE2, migrei todos os …

http://ericksasse.com.br/free­vs­freeandnil­vs­release/ 6/7
23/01/2016 Free vs. FreeAndNil vs. Release

Erick Sasse

Erick Sasse  esasse Desenvolvimento de software, tecnologia


esasse@gmail.com  esasse e afins

http://ericksasse.com.br/free­vs­freeandnil­vs­release/ 7/7