Você está familiarizado com FreeAndNil() , mas você o usa? Com que frequência? Você está usando certo? Tal como acontece com a maioria das coisas no desenvolvimento de software, é um tópico complicado. Então vamos ver o que os especialistas têm a dizer. Vamos debater os detalhes em uma discussão amigável com alguns de seus MVPs favoritos.
- Esta postagem no blog incluirá o replay, slides e muito mais após o webinar.
A pesquisa diz…
Quando você se inscreve no webinar , incluímos uma breve pesquisa para ver sua posição sobre o assunto. Durante o webinar, vamos comparar o consenso geral com o do nosso painel de especialistas MVP.
Ainda mais MVPs opinaram sobre o assunto e eu tenho alguns teasers de como eles votaram…
Deixei a legenda de que os gráficos significam por enquanto, você precisa participar do webinar para ver os detalhes, mas o uso de FreeAndNil() é dividido de maneira bastante uniforme se agruparmos as respostas em generalidades a favor e contra.
Se dividirmos as coisas em detalhes, é um pouco mais sutil. Novamente, sem a lenda, ainda.
Fazer cheques atribuídos é semelhante, mas diferenças um pouco mais pronunciadas.
- Q: Eu tenho um lema: se você criou algo, destrua no final da rotina! É por isso que eu uso muito FreeAndNIl()!
- R: Nem sempre é possível, mas entendo seu ponto de vista.
- P: A instanciação sob demanda geralmente é um padrão sensato e, portanto, você não terá nada para colocar no ponteiro!
- R: Belo ponto
- P: Esse cara faz alguma programação real?
- R: sim, muito. Sim, ele é um programador extremamente experiente e muito respeitado. Eu te prometo 🙂
- P: Chame você de objeto Dummy “Nil” 😛
- R: Bom ponto.
- P: Eu me sento corrigido.
- R: rs
- P: nil é uma ótima maneira de confirmar que não há nada referenciado, e se você SEMPRE liberar com FreeAndNil, seu código manterá que o ponteiro será nil se não for válido, caso contrário, é sempre um objeto válido.
- R: Ele atribui nil, mas há momentos em que você não precisa atribuí-lo a nil, ou quando você pode estar obscurecendo outras coisas.
- P: Como você pode dizer “sempre use interfaces” e depois também dizer “você nunca deve destruir algo que você não criou” – completamente inconsistente!
- R: Eu disse, “se você puder, use interfaces” e o ponto sobre a codificação de uma interface é que a contagem de referência é explicitamente projetada para lidar com isso.
- P: Existem vários casos de uso para Assigned e FreeAndNil. Se você não os estiver usando, ou não está usando esses casos de uso ou é um programador ruim. Dizer que não há razão para usá-los, ou que se você os estiver usando, não deveria estar, é completamente errado.
- R: Eu acredito que o Nick está dizendo é que usar verificações FreeAndNil e Assigned são um cheiro de código que você pode precisar de um design diferente. Além disso, o uso excessivo de FreeAndNil também obscurece as coisas.
- P: Existem muitas circunstâncias em que o código responsável por liberar um objeto não é o mesmo código que criou o objeto. O exemplo mais óbvio é um modelo de gerenciamento de memória de contagem de referência.
- R: certo
- P: Também deve obter uma visualização de desenvolvimento C++
- R: Sim, alguns dos MVPs usam ambos.
- P: F# usa o tipo Option (tipo união com Some e None) para evitar nil, e acredito que isso requer suporte na linguagem (no sistema de tipos). O Delphi fornece esse tipo de suporte?
- R: não que eu saiba…
- P: Por que você liberaria um objeto e não definiria o ponteiro para ele como nil?
- R: Se a referência não estiver disponível porque está saindo do escopo imediatamente, a atribuição não será necessária.
- P: O que Olaf acabou de explicar tem um nome: programação de culto de carga
- R: Esse era um conceito que eu estava pensando em vir para este webinar. Eu sou um grande crente em programação baseada em evidências. ,Tbh, eu tive que pesquisar o que significa “Cargo Cult”. Sim eu concordo. Mas como eu disse, se você está em sua própria estrada, ou há motoristas seguros, então FreeAndNil() é de uso agora. O que eu vejo na natureza, é muito diferente. Lembre-se, estou frequentemente trabalhando com equipes externas, com conjuntos de habilidades muito diferentes. Muitos deles não possuem a tag “Salvar Driver” (ainda)
- P: O artigo da wikipedia tem até esta declaração: “Verificações obsessivas e redundantes de valores nulos ou testar se uma coleção está vazia antes de iterar seus valores pode ser um sinal de programação de culto de carga”.
- R: rs
- P: Usamos métodos getter de propriedade que incluem verificações para atribuição de uma variável “f” e a construímos sob demanda… não construa todas as variáveis “f” antecipadamente. E nós freeandnil para ajudar a garantir que as chamadas subsequentes para a propriedade sejam gerenciadas e inicializadas adequadamente.
- R: certo
- P: FreeAndNil simula variáveis locais unique_ptr C++. O Delphi 10.4 finalmente introduziu o RAII, então pode haver um material unique_ptr mais explícito agora, mas eu tenho que manter o código Delphi 7, e então continuo usando FreeAndNil como unique_ptr que está faltando
- R: É sempre frustrante quando tenho que trabalhar com código para compiladores antigos também.
- P: “Não há problema em deixar um ponteiro definido para um objeto que foi liberado” – sério? Você já teve que depurar alguma coisa?
- R: Certo, não concordo com o tipo de difamação ilusória das habilidades de programação, mas vejo o que você está dizendo que é “pode causar problemas com o depurador, então você discorda”
- P: talvez você deva explicar a diferença exata entre x.free e FreeAndNil(x) Acho que nem todos aqui estão cientes da diferença
- R: FreeAndNil(x) free é o objeto, o mesmo que x.free, mas também define a referência para nil. Se você não definir a referência como nil, ela ainda estará apontando para o objeto liberado.
- P: Um campo de classe que faz referência a um objeto deve ser nil até que o objeto seja criado e, quando o objeto for liberado, deve ser colocado em nil. Essa conversa é absurda para mim.
- P: Exemplos de código?
- R: Se você observar os slides, há algumas postagens no blog que apontam para o código.
https://developpeur-pascal.fr/faut-il-vraiment-utiliser-freeandnil-dont-nos-programmes-en-pascal.html https://corneliusconcepts.tech/delphi-debates-freeandnil
- P: Eu realmente não entendo o motivo deste debate. Eu pensei que seria uma explicação de por que FreeAndNil deveria ser usado em vez de usar .Free e então := nil. Aqui parece que estamos discutindo o uso de FreeAndNil em objetos que nunca criei. Acho que perdi o enredo!
- R: A discussão são os prós e contras de usar o FreeAndNil e ter referências não atribuídas.
- P: Desenvolvi o SafeMM3 e encontrei um bug no FireMonkey. O Destructor usou “Free” para uma referência que deveria ter desaparecido, afinal, é um destruidor, mas então alguma operação SetFocus estava andando com ponteiros pendurados. Raramente você pode ter certeza de que a última operação em referência é realmente a última.
- R: bom ponto.
- P:O ponto é que o NIL é um valor real e verdadeiro no código e, por essa razão, será verificado essas situações (como rejeitar um NIL como Nick afirma), e como tal NIL não desaparece, então faz sentido NIL algo para certifique-se de que a memória seja realmente NIL e não algum valor antigo aleatório dos velhos tempos. Isso é especialmente importante quando você escreve código de alto desempenho de baixo nível, mas obviamente muito menos importante quando se está principalmente escrevendo código de alto nível, essencialmente criando scripts de módulos existentes juntos. As interfaces absolutamente têm muitos usos excelentes, mas às vezes precisamos simplesmente de ponteiros para registros ou classes, e acompanhar NIL ou não NIL é bastante crítico. Portanto, FreeAndNil tem seus usos, mas x.Free também; e x:=nil; Se o último falhar, o FreeAndNil pode falhar e estamos falando de um cenário multithread,
- R: Belo ponto Kim.
- P: Errado. Você nem sempre deve criar uma classe em seu construtor. Se é comum criar o objeto em seu primeiro uso, e depois deixá-lo criado para reutilização.
- R: Eu posso ver que há algumas pessoas tomando ambos os lados deste ponto de vista.
- P: O padrão de objeto nulo (é o que Nick chamou de objeto fictício) é bom para injetáveis, mas não para muitos criáveis
- P: Recentemente, tive uma falha grave devido ao acesso a um objeto liberado que não era nulo. Isso é realmente difícil de detectar. Se a variável sair do escopo, nil não é realmente necessário, mas você deve verificar o código com muito cuidado para evitar usá-lo posteriormente.
- R: Na minha opinião, se houver uma chance de sua referência ainda ser usada posteriormente, você deve atribuí-la a nil com FreeAndNil.
- Q: Ação := caFree Quando eu faço isso eu tenho que colocar um ponteiro nil? MinhaClasse := TMyClass.Create; MyClass := nil quando eu uso Action := caFree
- P: A questão chave provavelmente deveria ser… existe uma verdadeira desvantagem em usar freeandnil?
- R: Oculta as coisas e pode introduzir erros com inicialização lenta.
- P: Usar interfaces normalmente não é sobre gerenciamento de memória, misturar os dois (com a falta de documentação explícita) é uma série de desastres esperando para acontecer. Eu vi muitos códigos segurando referências de interface para objetos que foram liberados quando a contagem de referência foi para zero. Uma disciplina de gerenciamento de memória de sempre liberar explicitamente com FreeAndNil parece que deve ser inerentemente mais segura.
- R: talvez
- P: Acho que em um aplicativo multithreading faz sentido usar Assigned() e FreeAndNil(), quando as instâncias podem ser usadas temporariamente ou as interações com serviços/servidores remotos podem ser interrompidas e precisam de reconexão com essas instâncias temporárias.
- R: Sim, acho que vários dos MVPs concordam com você.
- P: Ada.Unchecked_Deallocation funciona como FreeAndNil pronto para uso. O mesmo vale para o procedimento Delete, ele destrói o cursor passado. Pena que os desenvolvedores Delphi raramente procuram inspiração em outros descendentes do Pascal
- R: Acho que há muito mais investigações sobre as técnicas e inovações de todas as linguagens – não apenas descendentes de Pascal – do que você pode perceber. Por exemplo, declarações de variáveis inline (que eu pessoalmente odiei quando foram lançadas) são inspiradas por outras linguagens que fizeram isso. Eles são muito ‘não-Pascal’, mas acabaram tendo algumas vantagens muito distintas que eram muito atraentes para serem ignoradas.
- P: Você nem sempre deve criar todos os objetos de uma classe em seu construtor. Se é comum, pelo menos para nós, criar o(s) objeto(s) somente se e quando forem necessários, e depois deixá-los criados para reutilização. Então, quando a classe é destruída, ela deve destruir as instâncias criadas. Assigned e FreeAndNill são vitais para isso.
- R: Inicialização lenta, sim
- P: Tem que largar, mas ótima discussão!
- R: Obrigado Gary.
- P: Para os computadores de hoje, os ciclos de CPU para FreeAndNil são insignificantes, mesmo para mecanismos 3D ou qualquer outra coisa. Isso não é 1980!
- R: como Nick e Thomas apontaram, é necessário que o desenvolvedor considere o motivo do FreeAndNil, então são necessários mais ciclos de desenvolvimento.
- P: estou aprendendo a desenvolver aplicativo mobile através do delphi 10.4 CE FMX, e, tenho muitas dúvidas e não encontro em lugar algum, a não ser nos grupos de telegram ou nos vídeos do 99coders – que tem uma didática fantástica, além de Márcio, Gledson Prego, Anderson Fiori e MobiusOne, que tem nos ajudado e muito. Mas, isso é pouco para uma aplicação tão antiga como o Delphi. Minhas dúvidas são: 1) Qual é o método correto e onde destruo os objetos(*) que são instanciados numa function/procedure na seção VAR? (*)jsonarray, jsonobject, frame, etc… >> 1a) esses objetos os destruo com o FreeAndNil, disposeOf, .free, =nil? >> 1b) qual é o melhor e mais eficaz método de destruição desses objetos? >> 1c) onde é o local (event) correto para destruição deles? onClose, onDestroy? 2) Por que o delphi causa muitos Memory Leaks de objetos que a gente tem certeza que eles estão sendo destruídos?
- P: Esta é uma ótima sessão (Marco)
- R: Sim, parece popular.
- P: Você poderia explicar por que FreeAndNil() não é threadsafe?
- R: Não é atômico. Você deve bloquear a referência antes da chamada para FreeAndNil.
- P: “Ponteiros pendentes” – um modelo de gerenciamento de memória cooperativo precisa garantir que os consumidores de objetos sejam notificados quando um objeto for liberado.
- P: FreeAndNil define como nil antes de liberar – então, embora você possa ter uma troca de contexto antes de liberar o objeto, você já terá definido o ponteiro para nil…
- P: Se liberar é a última ação, então Free(). Se uma variável for usada várias vezes, FreeAndNill()?
- R: se você for reutilizar a referência, então FreeAndNil
- P: O que o FreeAndNil realmente faz? Por que .Free não define a referência para nil?
- R: O Free verifica a referência para ver se ela está atribuída e, se estiver, destrói o objeto, mas ainda faz referência ao objeto destruído. FreeAndNil também atribui a referência ao nil.
- P: Infelizmente, as variáveis inline ainda não funcionam. se você usar as ferramentas de refatoração de pesquisa de referência “depois” de uma variável inline em uma unidade, ela quebra essas ferramentas 🙁
- R: Há mais trabalho e RSPs em relação à refatoração e variáveis inline. A refatoração (e coisas como a reformatação automática) pode ser um problema para construções de linguagem mais recentes.
- P: A única vantagem específica que o Pascal tinha sobre as linguagens baseadas em C… o requisito de declarar a seção de interface AND variáveis antes do uso. A maneira que torna possível obter uma visão geral do código apenas olhando para ele.
- R: sim
- P: Encontre meu projeto SafeMM3 no OSDN. Ao contrário do SafeMM e SafeMM2, é compatível com o Delphi recente, testado no Delphi 10.2. Encontrei ponteiros pendentes no FireMonkey, produzidos pela naked Free
- R: cuidado com ponteiros pendentes.
- P: E então essa vantagem foi “comprometida” pela declaração de variável inline e até mesmo pela dedução do tipo de dados…. Bzzzzzz….
- R: Eu amo variáveis inline.
- P: Onde estão os exemplos?
- R: Eu postei alguns links acima.
- Q: lembrando, estou vindo do clipper/harbour por onde comecei aos 14 anos de idade e fiquei lá até 2021, onde estava desistindo e assisti a um vídeo impulsionado do 99coders falando do Delphi, onde o título era algo assim: “o delphi morreu?” e ele mostrava que dá para fazer muita coisa via delphi, principalmente para mobile (android/ios) rsrs
- P: Como você faz ao usar DLLs e passar objetos como parâmetro? Você faz uma cópia do objeto e a envia de volta como um objeto de resultado?
- R: Depende, suponho.
- Q: mais uma pergunta aqui de alguém do Brasil: 3) porque tentaram usar o .DisposeOf se teve que voltar pro FreeAndNil( )
- P: C++ – Eu tenho experiência em C++ e é por isso que achei a falta de documentação explícita sobre interfaces Delphi tão irritante.
- R: ah, sim
- Q: 4) favor dar um bom exemplo de uso do freeAndNill() de forma eficaz a não deixar nenhum Memory Leak …
- P: Esses pontos trazem à tona a propriedade / ideias emprestadas em Rust
- R: Sim, Rust se inspirou muito no Delphi.
- P: Não tenho uma pergunta, mas quero agradecer pelo desenvolvimento do Delphi. Obrigada)
- R: Obrigado! Ainda bem que Delphi está aqui também!
- P: qual é uma boa fonte para entender a estrutura de design de interface
- R: Eu acredito que os livros de Nick Hodges discutem isso
- P: As interfaces não são thread-safe. Apenas o contador de referência dentro de TInterfacedObject é. Mas a atribuição de interface é uma operação não atômica e precisaria estar sob bloqueio.
- R: Sim, o livro de Dalija discute isso detalhadamente.
- P: Houve um comentário sobre “perder ciclos de CPU”… Quantas instruções de montagem são necessárias para “x = nil”? Se isso for feito em vários objetos em algum tipo de ciclo/loop, atribuir NIL pode afetar o desempenho se as variáveis não forem mais referenciadas após liberá-las, mas se as variáveis puderem ser referenciadas fora do loop posteriormente, é melhor saber se elas são realmente referenciando um objeto existente.
- R: Verifique a visualização da CPU e veja.
- P: MISRA C tem tudo a ver com programação de culto à carga. C permite instruções de linha única, mas MISRA C as proíbe. Portanto, é uma prática bastante industrial. nada do que se envergonhar
- R: ah
- P: Belo debate!
- R: Ele provou ser muito mais popular – e divisivo – do que pensávamos!
- P: @Nick, se você considera nunca usar FreeAndNil(), então em aplicativos baseados em eventos (não tão raros), como você pode evitar criar objetos em momentos desconhecidos e evitar criá-los duas vezes ou mais? O caso típico é quando o usuário clica em um botão e executa algum descendente do TThread. E se o usuário clicar duas vezes no mesmo botão, a 2ª vez quando o 1º TThread lançado pelo 1º clique não for finalizado.
- R: Talvez impedir que o botão seja clicado duas vezes? Essa parece ser uma preocupação válida.
- P: Consegui instanciar um objeto usando “assigned” só liberei o objeto da memória com “action: caFree” mas não apontei para “nil” como isso é possível?
- R: A menos que você chame FreeAndNil, ou atribua explicitamente a Nil, então free não anula a referência.
- P: exemplo, onde FreeAndNil mostrará erros no código: Com object.Free você não receberá uma exceção se acidentalmente usar o objeto. com FreeAndNil(object) você obterá a exceção imediatamente!exemplo: procedure TForm1.BT_Click(Sender: TObject); var sl: TStringList; begin sl:=TStringList.Create; tente finalmente sl.Free; //FreeAndNil(sl); fim; // — // outras coisas // — if (sl.Text = ”) then sl.Text:= ‘Hello World!’; fim;
- R: obrigado
- P: Existe alguma situação em que eu precise usar um objeto liberado? (mais frequentemente eu preciso “Nil” uma var sem liberar o objeto). Ou, talvez, FreeAndNil exista apenas para completar porque x.free não poderia “Nil” o var. Obrigado
- R: Na minha opinião, eu FreeAndNil quando há outras referências que possam referenciar depois que for nil.
- P: Nenhum código está livre de bugs. Você quer que os bugs falhem cedo e com força. O FreeAndNil ajuda a capturar bugs de “uso depois de grátis”.
- R: verdade
- P: Eu nunca chamo o destruidor diretamente, esse é o trabalho do Free, não é?
- R: sim
- P: Eu quase sempre uso freeandnil em componentes de terceiros, nunca confio no código de outras pessoas 😛
- P: Não tenho certeza se chamar diretamente o Destroy é realmente mais rápido do que usar o Free. Simplesmente porque Destroy é uma chamada de método virtual. Alguém tem que fornecer alguma referência para provar esse ponto
- R: verdade
- P: Criar um objeto em seu primeiro uso pode criar muitos problemas ao tentar fazer algo com esse objeto. Eu experimentei isso ao adicionar algumas funcionalidades ao InplaceEditor de um TCustomGrid.
- P: O ideal seria programar de forma que o compilador ajude a identificar os problemas… muita discussão aqui é sobre habilidade do programador.
- P: Referências de formulários globais – o IDE criará automaticamente um ponteiro global para formulários…
- P: Então você está chamando o IDE de louco? De Jim? Isso é apenas rude!
- R: 🙂
- P: Falando sobre variáveis inline “un-Pascal”, Ada desde o início tem o bloco declare-begin-end. Então não é “un-Pascal”, é só que você ainda não conhece a Ada. Mas Ada não termina com isso. O Delphi tinha recentemente obtido “vars inline” enquanto no Ada o desenvolvedor mais frequentemente gosta de “constantes inline” em vez disso. De fato, se algo for inicializado no início de um bloco, é provável que nunca mude até o final do escopo. Marcar coisas “constantes” ajuda a legibilidade e o raciocínio
- R: Sim! = Pascal. ️
- P: Se você usar o FreeAndNIL de forma persistente, não haverá ciclo de desenvolvedor adicional quando for usado. É apenas quando você não é consistente em seu uso…
- R: Suponho que seja um ponto válido.
- P: Posso dizer o quanto gostei dessa discussão instigante? Obrigada!
- R: fico feliz em saber.
- P: Quais livros de Dalija Prasnikar você recomendaria sobre o assunto de hoje?
- R: https://dalija.prasnikar.info/delphimm/index.html
- Q: Vou jogar meus dois centavos no ringue…. com declaração… tente não usá-los e certamente não os use para mais de uma coisa ….. apenas MHO
- R: Sim, esta é a minha opinião também – mas nem todos concordam, aparentemente – daí o debate.
- Q: qual usar então para destuir: .free disposeOf =nil freeAndNil() ??? qual realmente libera memória e a gente fica livre da porcaria do “Memory Leak”? obs.: delphi 10.4 CE / FMX / Mobile
- P: Como se chama o livro de Dalija?
- R: https://dalija.prasnikar.info/delphitspatt/
- P: Este webinar foi ótimo. Eu vou ser honesto, eu não estava esperando muito, mas francamente este tem sido um dos melhores webinars ultimamente…. Mais do mesmo por favor !!
- R: Anotado. Que bom que você gostou.
- P: Nunca usei FreeAndNil. Nunca vai – a menos que Nick comece a usá-lo 😀
- R: ah
- P: Uma discussão muito interessante sobre como lidar com variáveis de ponteiros…. Eu costumo descartar ou retornar os ponteiros para a memória depois de usá-los
- R: Sim. Isso é um padrão.
- P: Concordo totalmente com a sugestão de Holger: por favor, o Delphi pode parar de fazer um novo aplicativo com um formulário construído em torno de globais? Certamente vale um debate.
- R: Eu também pensei nisso.
- Q: link fornecido por vocês não funciona: https://developpeur-pascal.fr/faut-il-vraiment-utiliser-freeandnil-don’t-nos-programmes-en-pascal.html – este link não funciona (404 error)
- P: Obrigado, gostei da sessão!
- P: Sugira manter e publicar o chat também
- P: Tem que correr. Muitíssimo obrigado!!! Bom trabalho.
- P: Destruir sozinho é mais rápido que Free. A implementação do Free é “IF Assigned(Self) THEN Destroy”; então, ao chamar o Destroy diretamente, você está omitindo uma CHAMADA e uma verificação “Se atribuído” – você ainda está chamando o Destroy virtual…
- P: Se você quiser verificar a segurança do encadeamento de coisas da interface, escreva TInterfacedObject descendente que está invocando Sleep(10) em AddRef e Release. Eu escrevi referências sem bloqueio com o primitieve Compare-And-Exchange que está passando neste teste. Eu provavelmente posso fazer referência fraca thread-safe também
- Q: sinceramente, os nobres “gurus” não responderam a nenhuma de minhas perguntas. São 11 homens e mulheres que são os crânios da Pascal / Delphi e eu que estou começando e vindo do clipper / harbour, gostaria da vossa atenção, até mesmo para eu me sentir em casa!
- P: Sempre tento sempre que possível criar o objeto e liberar o mesmo objeto dentro da mesma rotina, dessa forma tenho muito mais controle e muito menos chance de problemas de memória e referência e r
- P: Falamos muito ao longo dos anos de uso de interfaces para gerenciamento automático de memória… e os registros gerenciados agora? Podemos fazer RAII em delphi… existe outro caminho?
- R: sim, o RAII introduz isso.
- P: se você compilasse as perguntas e respostas que estão sendo feitas e as publicasse seria excelente.
- A: Veremos sobre fazer isso.
- P: Entrei um pouco tarde, desculpe se isso foi discutido antes; se você obter o objeto filho como em (ParentObject.childObject) liberado de qualquer maneira, e então você freeAndNil parentObject … isso não pode ser seguro porque o tempo necessário para liberar cada objeto pode se cruzar e ser sequencial?
- R: Boa pergunta. Mesmo se você anular a referência, o objeto ainda será responsável por liberar seus filhos, enquanto os filhos usam um padrão de notificação para notificar o pai quando são liberados.
- P: Se você iniciar um thread em um clique de botão, parece óbvio que você deve estar preparado para executar vários threads :-), você não liberará objetos compartilhados em tal thread. Ou… você desativa o botão.
- R: sim
- P: quanto mais caro é FreeAndNil para manual Free seguido de atribuição manual gratuita?
- R: Em termos de CPU não requer muito, mas o que está comunicando.
- P: Gostei dessa discussão vívida de especialistas em programação
- P: O Delphi RTL usa GOTO 🙂
- R: sim
- P: Obrigado, mais sobre isso, por favor. +1
- R: certo
- P: Se você destruir um TJSONObject, ele também destruirá todos os objetos “GetValue as TJSONString”?
- P: Sugestão … podemos não ter apenas “não use com” … vamos ter o que ele tentou fazer … o que outras linguagens têm … e o que poderíamos começar a fazer com o delphi moderno nessa direção
- P: Os eventos clicados no botão não são entregues como resultado de serem GetMessage’d da fila de threads da interface do usuário? O segundo evento de clique não será entregue até que o primeiro seja processado, a menos que seja produzido programaticamente, o que seria um problema de reentrada. O que estou perdendo aqui?
- P: Mais goto na RTL desde que comecei a otimizar algumas funções do sistema sem fazer asm 😉
- P: Não é tão simples simplesmente desabilitar o botão, porque as coisas são mais complicadas. Eu uso algo como “demanda” da programação funcional. Assim, quando o botão clica pela primeira vez, a demanda contada por referência é criada, dedicada ao “primeiro clique”. A thread pode então fazer algumas coisas e pesquisar sua própria “demanda” para verificar se ainda é exigida. E tendo entrado em Sincronizar, verifique também se esta “demanda” específica ainda está em vigor. Quando o botão é clicado pela segunda vez, a demanda antiga é marcada como obsoleta e a nova demanda é implantada. Desta forma, o primeiro tópico recebe a mensagem: vá embora, não precisamos mais de você
- P: Wish: variáveis locais, estáticas que sobrevivem entre as chamadas (atualmente usam CONSTs locais atribuíveis)
- P: Obrigado