Duvidas na criacao/liberacao de um Form

Delphi

13/04/2006

Olá amigos, fazendo deste jeito eu libero corretamente o meu Form da memoria?

try
  FrmTeste := TFrmTeste.Create(nil);
  FrmTeste.ShowModal;
finally
  FrmTeste.Release;
end;



aproveito pra uma questão maluca, existe diferença no codigo acima com este abaixo? Tipo, tanto faz usar um ou outro, ou algum é melhor?

  FrmTeste := TFrmTeste.Create(nil);
  FrmTeste.ShowModal;
  FrmTeste.Release;


Desde já agradeço.

[]s


Titanius

Titanius

Curtidas 0

Respostas

Rjun

Rjun

13/04/2006

Acho que o correto seria isso:

FrmTeste := TFrmTeste.Create(nil); 
try 
  FrmTeste.ShowModal; 
finally 
  FrmTeste.Release; 
end; 


Pois ele só irá excecutar o finally se o form for criado. No seu exemplo ele entra no try, mas digamos que por algum motivo o form não seja criado, ele irá excecutar o finally e como não tem o form para ser liberado ele vai dar uma exceção.


GOSTEI 0
Titanius

Titanius

13/04/2006

[b:c3f5ba7e1b]RJun[/b:c3f5ba7e1b]

Mas no caso ele daria um excecao nao? Pois o try..finally gera execao ou nao? ele nao serve pra depois que tudo for feito ele executa o finally? se Fosse o try..except aih sim, ele nao daria o erro...


Esta correto?

[]s


GOSTEI 0
Michael

Michael

13/04/2006

Olá [b:dc01104bfb]Titanius[/b:dc01104bfb]!

O que o colega [b:dc01104bfb]RJun [/b:dc01104bfb]quis dizer é que se vc colocar o código de criação do formulário dentro do [b:dc01104bfb]try, [/b:dc01104bfb]e ele gerar uma exceção, o objeto não sera instanciado. E desta forma, o [b:dc01104bfb]Release [/b:dc01104bfb]dentro do [b:dc01104bfb]finally [/b:dc01104bfb]- que será sempre executado - poderia resultar em outro erro.

Quando se cria componentes, isto é, classes derivadas de [b:dc01104bfb]TComponent[/b:dc01104bfb], e se passa o [b:dc01104bfb]Owner [/b:dc01104bfb]como sendo nil, deve-se usar um try..finally para garantir a sua liberação posterior da memória. O código da instanciação da classe deve sempre ficar fora do [b:dc01104bfb]try..finally[/b:dc01104bfb], pelas razões já apresentadas.

Na edição 72 da revista ClubeDelphi, que deve estar chegando nas bancas, escrevi um artigo abordando a criação de componentes em run-time, onde é falado sobre isso que estamos discutindo aqui, e outras coisas mais. Acho q seria legal se vc pudesse dar uma olhada nele. ;-)

[]´s


GOSTEI 0
Titanius

Titanius

13/04/2006

Fala ae Michael... Eu li lá sua reportagem... era mesmo so uma duvida.. :d mas e sobre os codigos abaixo:

Codigo 01
FrmTeste := TFrmTeste.Create(nil);
try
 FrmTeste.ShowModal;
...
finally
 FrmTeste.Release;
end;


Codigo 02
FrmTeste := TFrmTeste.Create(nil);
FrmTeste.ShowModal;
...
FrmTeste.Release;


Existe alguma diferença?


GOSTEI 0
Massuda

Massuda

13/04/2006

Tem um ponto que acho importante esclarecer...
Pois o try..finally gera execao ou nao? ele nao serve pra depois que tudo for feito ele executa o finally? se Fosse o try..except aih sim, ele nao daria o erro...
Tanto try..finally como try..except servem para [b:66d5ea8f67]tratar exceções[/b:66d5ea8f67], nenhum deles gera exceções.

O [b:66d5ea8f67]try..except[/b:66d5ea8f67] define um trecho de código que deve ser executado [b:66d5ea8f67]apenas se[/b:66d5ea8f67] ocorrer uma exceção em um determinado trecho de código...
try
  // código que pode gerar exceção
except
  // código que trata exceções
end;
...enquanto o [b:66d5ea8f67]try..finally[/b:66d5ea8f67] define um trecho de código que deve ser executado sempre, independente de ocorrer ou não uma exceção em um determinado trecho de código...
try
  // código que pode gerar exceção
finally
  // código que deve ser sempre executado
end;


...mas e sobre os codigos abaixo:...
O código 01 trata a possibilidade de ocorrer exceção enqanto o form estiver sendo exibido enquanto o código 02 não. Era isso que você queria saber?

Note que enquanto o form estiver visível e sendo manipulado pelo usuário (o ShowModal só retorna quando o form for fechado), podem ocorrer exceções.


GOSTEI 0
Titanius

Titanius

13/04/2006

Valeu massuda.. era isso mesmo...


[]s


GOSTEI 0
Massuda

Massuda

13/04/2006

Titanius, uma coisa interessante é a diferença entre seu código original...
try 
  FrmTeste := TFrmTeste.Create(nil); 
  FrmTeste.ShowModal; 
finally 
  FrmTeste.Release; 
end;
...e o código que o Rjun sugeriu...
FrmTeste := TFrmTeste.Create(nil); 
try 
  FrmTeste.ShowModal; 
finally 
  FrmTeste.Release; 
end;


Embora sejam parecidos, existe um problema se ocorrer uma exceção ao tentar criar o TFrmTeste.

No código que o Rjun sugeriu, essa exceção não seria tratada pelo try..finally do exemplo e deve (ou pelo menos, deveria) ser tratada em outro ponto do programa. Nesse caso, o try..finally nem chega a ser executado.

O problema com seu código é que a exceção gerada em TFrmTeste será tratada pelo código. Como teve uma exceção em TFrmTeste.Create, o valor de FrmTeste é indefinido (pode ser nil, mas isso não é garantido); resultado: ao executar o código do finally, ocorre nova exceção (provavelmente um AV) que não tem relação com o problema original. Isso é fonte de bugs do tipo ´ocorre AV ao destruir o form´ quando na verdade o problema é ´não estou conseguindo criar o form´; num exemplo pequeno é fácil perceber isso, mas num código real isso nem sempre é óbvio.


GOSTEI 0
Martins

Martins

13/04/2006

Tem um ponto que acho importante esclarecer...


é isso aí mesmo [b:a6e0dea4f3]Massuda[/b:a6e0dea4f3], :wink:


GOSTEI 0
Marco Salles

Marco Salles

13/04/2006

de fato colocar o try depois da instrução pode evitar algum constragimento .. [b:58a364b032]Mas não acho isto fundamental[/b:58a364b032] , a não ser que voce esteja sobrescrevendo o método OnCreate de algum Formulário.. Fora isto acredito , qua a instrução FrmTeste := TFrmTeste.Create(nil) não gerará nenhuma exceção

Porém caso voce esteja sobrescrevendo o método OnCretae , e ocorrer de ser inevitável que alguma exceção possa ser lançada , quando voce tiver inicializando os dados de algum Objeto , voce pode , ao inves de usar o Try Except continuar com o Try Finally.. evitando apenas que seje executado a instrução Release

Por exemplo , ao inves disso
Try 
  FrmTeste := TFrmTeste.Create(nil); 
  try
     FrmTeste.ShowModal; 
  finally 
    FrmTeste.Release; 
  end;
except
 on excption do
   showmessage(´erro´)
end;


Pode-se fazer isto

try
  FrmTeste:=TFrmTeste.Create(nil);
   FrmTeste.ShowModal;
  finally
   if assigned(FrmTeste) then
      FrmTeste.Release
  else
     showmessage(´Erro´)
  end;


é muito importante ter em mente que em um programa voce deve ter mais instruçoes try Finally , algumas instruçoes Raise e pouquisimas Try Except.
Na verdade um numero maior de Try Except no seu codigo indica erros no fluxo de programas e possivelmente um mau entendimento do papel das exceçoes da Linguagem

o Bloco Try finally é indicado sempre na proteção de um codigo , para evitar estouro de memória ou esgotamento de recursos caso alguma exceção seje gerada.. alem de como ja foi enfatizado toda a instrução que esteja apos o Finally sempre sera executada <salvo finalizaçoes bruscas no Programa >


GOSTEI 0
Fabiano Góes

Fabiano Góes

13/04/2006

Ai galera o que exatamente faz o :

FrmTeste.Release;



GOSTEI 0
Tdqr

Tdqr

13/04/2006

libera da memoria .... seria o mesmo que free , so que para form vc usa release


GOSTEI 0
Marco Salles

Marco Salles

13/04/2006

Ai galera o que exatamente faz o : Código: FrmTeste.Release;


esta na biblia do delphi 5.0 , não me lembro de ter visto na biblia do delphi 7.0 , e esta no Artigo do Michel na edição 72

O método Release do formulário é semelhante ao método Free dos oBjetos , mas a destruição do Formulário é Retardada para que todas as mensagens do Windows , bem como todos os manipuladores de evento relativos ao formulário em si ou ao seus componentes sejam executadas . Só após isto sera efetivado a Destruição do Form

Se bobear (Nada foi falado,em nenhuma biografia que ja li ) mas não devemos nos surpreender se Relase Chamar Free, é so um pallpite


GOSTEI 0
Fabiano Góes

Fabiano Góes

13/04/2006

Valeu ´Marco Salles´.
Um grande abraço !!!!


GOSTEI 0
POSTAR