Delphi: Parent e Owner - O que são?

Olá pessoal, nesta quick tip vamos esclarecer uma dúvida muito comum entre os desenvolvedores Delphi. Quem são Parent e Owner.

Olá pessoal, nesta quick tip vamos esclarecer uma dúvida muito comum entre os desenvolvedores Delphi. Quem são Parent e Owner. O Owner de um componente é o seu proprietário, é o responsável por destruir o componente quando ele (o Owner) for destruído. Quando criamos um componente dinamicamente, temos que passar o seu Owner no construtor. Quando inserimos um componente no formulário em tempo de design, ou seja, quando um componente é arrastado para o formulário, o Delphi cria uma instância do mesmo, passando o formulário como parâmetro no construtor do componente, indicando que ele é o owner do component.

Como podemos ver no create de TComponent, se AOwner for <> nil, então é executado o método InsertComponent do AOwner, passando o próprio objeto que está sendo criado como parâmetro. Este método por sua vez, se encarregará de adicionar o componente criado na lista de componentes dos quais o Owner é o responsável. Pronto, assim está estabelecida a relação “Pai“ e “Filho” dos componentes. Com isso, o Owner torna-se proprietário, responsável pela liberação dos componentes filhos da memória quando o mesmo for destruído, isso significa dizer que, ao acionar o destructor do formulário, automaticamente o formulário chama o destrutor de cada um de seus componentes filhos.

Se observarmos o código acima, vemos que o método DestroyComponents(que é executado no destroy de TComponent), se encarrega de percorrer a lista de componentes e destruir cada um deles. Já o parent, estabelece também uma relação de conteúdo e container. Enquanto o conceito de owner é inserido a partir de TComponent, o conceito de parent começa a partir de TControl(um nível abaixo de TComponent). O parent de um component é o container no qual o mesmo está inserido. O funcionamento é bem semelhante ao Owner, uma das diferenças fica por conta do momento em que o controle é adicionado à lista de controles do Parent. Enquanto no caso do owner esta rotina fica no construtor do TComponent, no caso do parent a mesma encontra-se no momento da atribuição do parent, ou seja, no método SetParent de TControl.

Observando o código àcima, podemos ver que ao atribuirmos o parent de um control, o mesmo é inserido na lista de controles do parent através do método InsertControl. Outra diferença fica por conta da destruição dos objetos filhos quando o parent é destruído, no caso do Owner temos esta rotina no destrutor do próprio TComponent, enquanto que no caso do Parent, esta rotina fica por conta de uma classe filha de TControl(TWinControl). Se observarmos o destructor da classe TWinControl(que está logo abaixo da classe TControl), poderemos ver a semelhança com a responsabilidade que o Owner tem com seus componentes de liberar os mesmos da memória.

Como podemos ver no bloco destacado acima, percorre-se a lista de controles(dos quais o controle em questão é o parent), e destroem-se cada um deles(assim como ocorre no destrutor de TComponent). Se observarmos a hierarquia da VCL, veremos que a classe TComponent possui o atributo Components enquanto que a classe TControl possui também o atributo FControls, ambas são do tipo TList, onde armazenam respectivamente.

Abaixo podemos ver um exemplo destas relações.

No exemplo acima, podemos ver que o panel não é o Owner de nenhum component. Porém o form é o owner de todos, pois conforme falado acima, ao arrastar um componente para o form em tempo de design o Delphi passa o form como Owner para o construtor do componente. De acordo com o exemplo acima, vemos também que os controles que estão dentro do Panel, são os controles que possuem o panel como Parent. Neste exemplo. Se destruirmos o Panel, o mesmo executará o destroy de TWinControl(seguindo a hierarquia) que por sua vez irá destruir cada um de seus objetos filhos registrados em FControls. Por outro lado, se destruirmos o formulário, o mesmo executará o destroy de TComponent(também seguindo sua hierarquia) que por sua vez irá destruir cada um de seus filhos registrados em FComponents. Com estes conceitos definidos, fica fácil perceber porque não precisamos destruir cada controle do formulário, pois quando destruímos um formulário, este por sua vez, destrói todos os componentes e controles no qual é o Owner ou o Parent. É isso aí pessoal, espero que tenham compreendido um pouco mais sobre o funcionamento da arquitetura dos componentes do Delphi, eu tentei ser breve e objetivo, apesar do assunto ser um pouco difícil de explicar textualmente.

Artigos relacionados