destruir objeto

Delphi

11/09/2006

bom dia!
estou criando objetos, em tempo de execução, mas não estou conseguindo destrui-los, so consigo destruir, quando o form e fechado gostaria de destrui-los ?

constructor TRadioList.Create(AOwner: TComponent;CaptionList: TStringList);
begin
with TRadioGroup.Create(AOwner) do begin
Parent := AOwner as TWinControl;
end;
end;


destructor TRadioList.Destroy;
begin
inherited Destroy;
end;


Airto

Airto

Curtidas 0

Respostas

Marco Salles

Marco Salles

11/09/2006

bom dia! 
estou criando objetos, em tempo de execução, mas não estou conseguindo destrui-los, so consigo destruir, quando o form e fechado gostaria de destrui-los ? 


acho que é porque o proprietário do objeto é a propria aplicação...
sempre que voce criar um componente ou um formulário que terá seu
tempo de vida definido , use Nil como Proprietário.. Isto diz ao delphi , que será voce (desenvolvedor) o responsável por liberar a memoria ocupada pelos objetos criados

constructor TRadioList.Create(AOwner: TComponent;CaptionList: TStringList); begin with TRadioGroup.Create([b:6d7d062d3d]nil[/b:6d7d062d3d]) do begin Parent := AOwner as TWinControl; end; end;



GOSTEI 0
Rodc

Rodc

11/09/2006

Acho que seu código deveria ser assim:
private
  FRadioGroup: TRadioGroup;
....

constructor TRadioList.Create(AOwner: TComponent;CaptionList: TStringList); 
begin 
  FRadioGroup.Create(Self);
  with FRadioGroup do 
  begin 
    Parent := Self; 
  end; 
end; 


destructor TRadioList.Destroy; 
begin 
  FreeAndNil(FRadioGroup);
  inherited Destroy; 
end;



GOSTEI 0
Marco Salles

Marco Salles

11/09/2006

sempre que voce criar um componente ou um formulário que terá seu tempo de vida definido , use [b:d356b217fd]Nil[/b:d356b217fd] como Proprietário.. Isto diz ao delphi , que será voce (desenvolvedor) o responsável por liberar a memoria ocupada pelos objetos criados


isto é ponto.....


  Parent := Self; 


esta corereto...Pois indica o que o componente criado estara contido visualmente no Formulário


GOSTEI 0
Airto

Airto

11/09/2006

ok!, como e possivel, apos o objeto criado, eu destruir e cria-lo novamente sem fechar o form?


GOSTEI 0
Massuda

Massuda

11/09/2006

Isso é perfeitamente válido...
procedure TSeuForm.AlgumBotaoClick(Sender: TObject);
begin
  // destrói e...
  FreeAndNil(FRadioGroup); 

  // ...cria de novo
  FRadioGroup.Create(Self); 
  with FRadioGroup do begin 
    Parent := Self; 
    ...
  end; 
  ...
end;



GOSTEI 0
Marco Salles

Marco Salles

11/09/2006

Isso é perfeitamente válido...Código: procedure TSeuForm.AlgumBotaoClick(Sender: TObject); begin // destrói e... FreeAndNil(FRadioGroup); // ...cria de novo FRadioGroup.Create(Self); with FRadioGroup do begin Parent := Self; ... end; ... end;


[b:2288933852]claro[/b:2288933852] , desde que seje do formulário a responsabilidade de destruir o Objeto.. mas não parece ser o caso.. O tempo de vida do objeto não esta relacionado ao tempo de vida do formulário <Pelo menos é o que parece>..


GOSTEI 0
Airto

Airto

11/09/2006

isso mesmo, o tempo de vida do objeto, nao depende do formulario, ele podera ser criado e destruido, sem fechar o formulario?
ainda nao consegui entender o funcionamento para destruir o objeto, sem fechar o formulario?


obrigado


GOSTEI 0
Marco Salles

Marco Salles

11/09/2006

ainda nao consegui entender o funcionamento para destruir o objeto, sem fechar o formulario?

eu acho que talves , voce não tenha entendido , como criar o objeto

Veja , voce reclamou que não estava conseguindo destruir o formulário

Eu diisse que era porque voce estava usando como proprietário do Objeto a Applicação.. E isto no seu caso não estava certo

Depois apareceu um Self como proprietario.. Apesar disso não estar errado , pelo que eu entendi no seu caso tab não serve

Então , voce deve criar o seu objeto passando Nil como proprietário

Feito esta etapa , voce pode destruir o bojeto , recria-lo , destrui-lo novamente etcc... Qual a sua dúvida


GOSTEI 0
Rodc

Rodc

11/09/2006

Pelo que eu entendi você está fazendo um componente, certo? E dentro do componente você quer fazer aparecer outro componente, certo? É por isto que o Owner tem de ser Self (ou seja, o reponsável por ele é componente principal). Não entendi o que tem a ver formulário (TForm) com destruir o seu subcomponente. :roll:


GOSTEI 0
Airto

Airto

11/09/2006

o que acontece e o seguinte:
Estou criando varios radiogroup, dentro de um scroolbox! da mesma forma que estou criando, gostaria de destrui-los, sem precisar fechar o form ?


TRadioList = class
procedure TOnClick(Sender: TObject);
private
public
constructor Create(AOwner : TComponent;CaptionList: TStringList);
destructor Destroy; override;


end;

var

RadioList : TRadioList;

constructor TRadioList.Create(AOwner: TComponent;CaptionList: TStringList);
begin

with TRadioGroup.Create(AOwner) do begin
Parent := AOwner as TWinControl;
Left := 150;
Font.Style:=[];
Font.Size := 8;
Name := xxx.. tag := tag;
Height := 35;
Columns := 3;
Width := 417;
Items.Add(´´);
Items.Add(´´);
Items.Add(´´);
OnClick:=TOnClick;

end;


procedure TRadioList.TOnClick(Sender: TObject);
begin

showmessage(´ok´),
end;

end;


destructor TRadioList.Destroy;
begin
inherited Destroy;
end;



RadioList := TRadioList.Create(Scr_Monitoramento,Lista_Rad);


GOSTEI 0
Rodc

Rodc

11/09/2006

Isto não é um componenente então, certo? Eu aconselho você afazer isto em um componente, mas blz...

Duas coisas: De que você está herdando a classe TRadioList? Outra coisa AOwner é o formulário Scr_Monitoramento, quando você passa AOwner nos parâmetros do Create você está dizendo que o responsável pela destruição do componente é o AOwner, ou seja, Scr_Monitoramento. Parent é onde o componente será exibido, no caso ele será exibido dentro do form Scr_Monitoramento. Eu imagino que você esteja querendo exibi-lo dentro de um ScrollBox.


GOSTEI 0
Rodc

Rodc

11/09/2006

Não entendi direito o que você quer fazer, mas tenta o código abaixo para ver se funciona...
TRadioList = class(TScrollBox) 
  procedure TOnClick(Sender: TObject); 
  private 
    Opcoes: array[0..10] of TRadioGroup;
  public 
    constructor Create(AOwner : TComponent; CaptionList: TStringList);
    destructor Destroy; override; 
end; 

var 

RadioList : TRadioList; 

constructor TRadioList.Create(AOwner: TComponent; CaptionList: TStringList); 
var x:integer;
begin 
  inherited Create(AOwner); // Chama o create do TScrollBox

  for x:=0 to CaptionList.Items.Count do
  begin 
    Opcoes[x] := TRadioGroup(Self); // o responsável por liberar a memória é o próprio TRadioList
    with Opcoes[x] do 
    begin 
      Parent := Self; // Ele será exibido dentro do TScrollBox
      Left := 50; 
      Font.Style:=[]; 
      Font.Size := 8; 
      Height := 35; 
      Top := 35 * x + 2; // Coloca um embaixo do outro
      Columns := 3; 
      Width := 417; 
      Items.Add(´´); 
      Items.Add(´´); 
      Items.Add(´´); 
      OnClick:=TOnClick;   
    end;
  end;
end; 

procedure TRadioList.TOnClick(Sender: TObject); 
begin 
  showmessage(´ok´), 
end; 

destructor TRadioList.Destroy; 
int x:integer;
begin 
  // Destroi os componentes criados
  for x:=0 to 10 do
    if Assigned(Opcoes[x]) then
      FreeAndNil(Opcoes[x])

  inherited Destroy; 
end;


Chama assim:
RadioList := TRadioList.Create(Scr_Monitoramento,Lista_Rad);


GOSTEI 0
Airto

Airto

11/09/2006

esta ocorrendo esse erro : um controle não pode ter próprio como seu pai

Parent := Self;


GOSTEI 0
Rodc

Rodc

11/09/2006

esta ocorrendo esse erro : um controle não pode ter próprio como seu pai Parent := Self;

Tenta assim:
Opcoes[x].Parent := Self;

ou assim:
Opcoes[x].Parent := AOwner;

mas este último caso fará o componente aparecer no form, e não no Scroll.
Coloca a mensagem de erro em inglês, caso continue a acontecer...


GOSTEI 0
Marco Salles

Marco Salles

11/09/2006

independentemente do fim que levou este tópico , com estou nele desde do inicio e fui acompanhando de perto o desenrolar, gostaria de acrescentar alguns conceitos que passaram despercebidos.

[b:6a96306c6d]A pergunta inicial foi: Como destruir objetos que foram criados...[/b:6a96306c6d]

A primeira dica afirmou que não se deve usar a[b:6a96306c6d] aplicação [/b:6a96306c6d]como [b:6a96306c6d]proprietario[/b:6a96306c6d] de qualquer componente criado em [b:6a96306c6d]RumTiime [/b:6a96306c6d]

Surgiu depois um conflitante entre [b:6a96306c6d]self[/b:6a96306c6d] e [b:6a96306c6d]Nil[/b:6a96306c6d]... O fato que ainda assim o amigo , não estava conseguindo destruir os objetos criados.

Tudo ficou mais claro , para mim , quando ele resolveu colocar de maneira completa a sua classe e o modo como estava fazendo

TRadioList = class procedure TOnClick(Sender: TObject); private public constructor Create(AOwner : TComponent;CaptionList: TStringList); destructor Destroy; override; end; ......................................... var RadioList : TRadioList; constructor TRadioList.Create(AOwner: TComponent;CaptionList: TStringList); begin with TRadioGroup.Create(AOwner) do begin Parent := AOwner as TWinControl; //outras coisa mais OnClick:=TOnClick; end; procedure TRadioList.TOnClick(Sender: TObject); begin showmessage(´ok´), end; end; destructor TRadioList.Destroy; begin inherited Destroy; end; RadioList := TRadioList.Create(Scr_Monitoramento,Lista_Rad);


bem , estamos diante de um [b:6a96306c6d]erro conceitual[/b:6a96306c6d]... Na realdidade uma armadilha que muitas das vezes confude a nossa percepção , nesse assunto.

Quando for executado o comando
[b:6a96306c6d]RadioList := TRadioList.Create(Scr_Monitoramento,Lista_Rad);[/b:6a96306c6d]
sera executado o [b:6a96306c6d]método constructor [/b:6a96306c6d]da classe TRadioList , fazendo com que seje criado o [b:6a96306c6d]Objeto RadioList [/b:6a96306c6d], e alem disso sera atribuido para a variavel RadioList um[b:6a96306c6d] ponteiro [/b:6a96306c6d], para que possamos acessar os [b:6a96306c6d]métodos[/b:6a96306c6d] definidos pela classe[b:6a96306c6d] TRadioList[/b:6a96306c6d]...

Por outro lado , se [b:6a96306c6d]olharmos[/b:6a96306c6d] para o método construtor , quando for executado o comando
[b:6a96306c6d]with TRadioGroup.Create(AOwner) do [/b:6a96306c6d]
sera criado , sem nenhum [color=darkred:6a96306c6d][b:6a96306c6d]vinculo[/b:6a96306c6d][/color:6a96306c6d] com Os objetos da classe [color=darkred:6a96306c6d][b:6a96306c6d]TRadioList[/b:6a96306c6d][/color:6a96306c6d] , os objetos da classe[color=darkred:6a96306c6d][b:6a96306c6d] TradioGroupBox[/b:6a96306c6d][/color:6a96306c6d]... e o pior de tudo é que não se tem nenhum [color=darkred:6a96306c6d][b:6a96306c6d]ponteiro[/b:6a96306c6d][/color:6a96306c6d] para esses objetos , ficando a priori , sem ter como[color=darkred:6a96306c6d][b:6a96306c6d] acessa-los[/b:6a96306c6d][/color:6a96306c6d]

A destruição dos objetos da classe TRadioList , ñesse modelo que fora proposto , não tem interferencia nenhuma com os objetos RadioGroupBox criados


Se formos olhar do ponto de vista conceitual , um método constructor de uma classe serve para iniciarlizar seus atributos e não para isntanciar objetos de outra classe. Isto foge acredito eu , dos principios de POO

Claro que ate conseguimos , definindo um Proprietario correto , acessar este objetos criados... Porem isto ocore independemente do Modelo de classe criado (TradioList).. Alem do mais , se optarmos por esta solução , estaremos mais uma vez recorrendo a uma má prática que deve ser evitada..

Contudo , não me propus a criar um modelo correto.Algo que o amigo rodoc ou qualquer outro possa faze-lo. Mas sim deixar que esta mensagem , possa servir de criticas por outros usuários que futuramente lerão o tópico , mesmo que Airto nen mais o leia...

espero ter sido claro.


GOSTEI 0
POSTAR