Ir para conteúdo
  • Cadastre-se

Dúvida sobre destruição da Classe


Ver Solução Respondido por valterpatrick,
  • Este tópico foi criado há 247 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

  • Membro Pro Verificado
Postado

Olá a todos,

Estou dando uma estudada nos componentes do ACBr e me deparei com uma dúvida na classe TACBrConsultaCNPJWSBrasilAPI presente na unit ACBrConsultaCNPJ.WS.BrasilAPI.

A mesma possui uma procedure Executar onde é implementado um código que varre um array de objetos Json e preenche a resposta.

São declarados dois objetos para tal LJSon que representa o array e o LJsonObject que representa cada objeto dentro do array.

Porém ao final o LJsonObject não precisa ser destruído... Na verdade reproduzi o código e se tentar destruir dá erro.

Fui indo cada vez mais fundo nas classes usadas (units ACBrJSON e JsonDataObjects_ACBr), porém não consegui entender o motivo de não precisar destruir o objeto.

Alguém poderia me explicar?

Desde já agradeço a atenção

  • Consultores
  • Solution
Postado

Ao destruir o LJSon, está destruindo também o LJsonObject, já que LJsonObject é um objeto que está dentro de LJSon.
Quando instancia o LJsonObject, está pegando a referência na memória, não uma cópia, por isto que ao destruir LJSon, é destruido também o LJsonObject.

  • Curtir 1

Valter Patrick
Gerente de Projetos na empresa CTEC
Consultor ACBr
(33)98400-0936
GitHub: https://github.com/valterpatrick

Ajude o Projeto ACBr crescer - Assine o Clube PRO                    

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  ícone Discórdia Discord   

  • Membro Pro Verificado
Postado
51 minutos atrás, valterpatrick disse:

Ao destruir o LJSon, está destruindo também o LJsonObject, já que LJsonObject é um objeto que está dentro de LJSon.
Quando instancia o LJsonObject, está pegando a referência na memória, não uma cópia, por isto que ao destruir LJSon, é destruido também o LJsonObject.

Oi meu amigo... Tudo bom?

Obrigado pela explicação, faz sentido.

Só não consegui achar no código onde exatamente isso acontece.

Na linha 81 da unit ACBrConsultaCNPJ.WS.BrasilAPI acontece a criação do objeto:

      LJsonObject := LJSon.ItemAsJSONObject[I];

Como você disse, está dentro do LJSon, pois inclusive usa uma propriedade desse objeto, a ItemAsJSONObject. Tal propriedade usa a função GetItemAsJSONObject (linha 886 da unit ACBrJSON) para leitura.

É aqui que estou me perdendo nesse conceito de "dentro do objeto"... Dentro dessa função temos a seguinte estrutura (removi as diretivas de compilação, exemplo está somente para Windows):

function TACBrJSONArray.GetItemAsJSONObject(const AIndex: Integer): TACBrJSONObject;
var
  LJSON: TJsonObject;
begin
  LJSON := FJSON.Items[AIndex].ObjectValue.Clone;
  try
    Result := TACBrJSONObject.Create(LJSON);
    Result.OwnerJSON := True;
    FContexts.Add(Result);
  except
    LJSON.Free;
    raise;
  end;
end;

Suponho que a linha que faz criar o objeto "dentro" do LJson do exemplo é a linha:

LJSON := FJSON.Items[AIndex].ObjectValue.Clone;

Mas ao tentar estudar esse ObjectValue e esse Clone estou me perdendo.

Vou tentar estudar esse código para ver se compreendo melhor.

Desde já agradeço a ajuda

 

 

  • Membro Pro Verificado
Postado
18 minutos atrás, Daniel Simoes disse:

A sua IDE está acusando vazamento de memória ?

Quando uma lista de objetos é destruída, todos os itens dela, são destruídos antes

Oi @Daniel Simoes, tudo bom?

Não, na verdade se tento destruir o objeto gera o erro "invalid pointer value", pois conforme o @valterpatrick explicou, o objeto (LJsonObject) está apontando para dentro de outro objeto (LJSon) que já foi destruído, portanto esse endereço de memória não existe mais.

Estou apenas estudando o código e melhorando meus conhecimentos na IDE.

  • Curtir 1
  • Consultores
Postado
45 minutos atrás, bnobre disse:

Oi @Daniel Simoes, tudo bom?

Não, na verdade se tento destruir o objeto gera o erro "invalid pointer value", pois conforme o @valterpatrick explicou, o objeto (LJsonObject) está apontando para dentro de outro objeto (LJSon) que já foi destruído, portanto esse endereço de memória não existe mais.

Estou apenas estudando o código e melhorando meus conhecimentos na IDE.

Creio que ai seria bom você pesquisar mais sobre orientação a objetos, variaveis e etc.
Talvez fazendo esta pergunta diretamente ao chatgpt e passando algumas outras informações, ele consiga te passar uma explicação mais concisa.

Valter Patrick
Gerente de Projetos na empresa CTEC
Consultor ACBr
(33)98400-0936
GitHub: https://github.com/valterpatrick

Ajude o Projeto ACBr crescer - Assine o Clube PRO                    

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  ícone Discórdia Discord   

  • Membro Pro Verificado
Postado
Agora, valterpatrick disse:

Creio que ai seria bom você pesquisar mais sobre orientação a objetos, variaveis e etc.
Talvez fazendo esta pergunta diretamente ao chatgpt e passando algumas outras informações, ele consiga te passar uma explicação mais concisa.

Sim... Na verdade parece que a "mágica" acontece com o uso de ponteiros na classe TJsonDataValue da unit JsonDataObjects_ACBr.

Muito interessante 😅

 

 

  • Membro Pro Verificado
Postado

Oi pessoal... Acho que a "mágica" está aqui:

(Linha 2301 da unit JsonDataObjects_ACBr)

function TJsonDataValue.GetObjectValue: TJsonObject;
begin
  if FTyp = jdtObject then
    Result := TJsonObject(FValue.O) //******************* Aqui
  else if FTyp = jdtNone then
    Result := nil
  else
  begin
    TypeCastError(jdtObject);
    Result := nil;
  end;
end;

Quando o tipo armazenado é um objeto(jdtObject) ele retorna o TJsonObject(FValue.O).

O FValue.O é um ponteiro, apontando para o local onde está o objeto da lista de arrays em questão. ;-)

O detalhe é que eu não entendi esse código TJsonObject(FValue.O). Basicamente ele usa o nome da classe como se fosse uma função e o parâmetro é o ponteiro. Isso executa alguma propriedade ou função dentro da classe TJsonObject? Se sim qual?

  • Curtir 1
  • Consultores
Postado

Entender o funcionamento interno de determinados códigos é importante.

Com isto você consegue desenvolver códigos cada vez melhores, mais seguros e mais rápidos.

 

 

Valter Patrick
Gerente de Projetos na empresa CTEC
Consultor ACBr
(33)98400-0936
GitHub: https://github.com/valterpatrick

Ajude o Projeto ACBr crescer - Assine o Clube PRO                    

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  ícone Discórdia Discord   

  • Membro Pro Verificado
Postado
1 minuto atrás, valterpatrick disse:

Entender o funcionamento interno de determinados códigos é importante.

Com isto você consegue desenvolver códigos cada vez melhores, mais seguros e mais rápidos.

 

 

Exato... Por isso que estou tentando entender O PORQUE :-D

Estou no caminho certo em meu entendimento?

  • Membro Pro Verificado
Postado

Finalmente descobri o significado da linha abaixo:

TJsonObject(FValue.O)

Está aplicando um Typecast, dizendo que FValue.O trata-se de um TJsonObject. :-DFonte: https://docwiki.embarcadero.com/RADStudio/Athens/en/Expressions_(Delphi)#Typecasts

Já FValue é um um Record onde o field O recebe valores do tipo ponteiros. Portanto FValue.O possui o endereço de memória onde estão gravados objetos json, daí o TypeCast para trata-los como tal.

Só ainda não consegui descobrir em qual linha o FValue.O recebe esses endereços.

 

 

  • Curtir 1
  • Este tópico foi criado há 247 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.