Pergunta

Em um mundo onde a alocação manual de memória e os ponteiros ainda dominam (Borland Delphi), preciso de uma solução geral para o que considero um problema geral:

Num determinado momento, um objeto pode ser referenciado em vários locais (listas, outros objetos, ...).Existe uma boa maneira de acompanhar todas essas referências para que eu possa atualizá-las quando o objeto for destruído?­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Foi útil?

Solução

Se você quiser notificar outras pessoas sobre mudanças, você deve implementar o "Padrão Observador".O Delphi já fez isso para você, para os descendentes do TComponent.Você pode chamar o método TComponent.FreeNotification e fazer com que seu objeto seja notificado quando o outro componente for destruído.Isso é feito chamando o método Notification.Você pode remover-se da lista de notificações chamando TComponent.RemoveFreeNotification.Veja também esta página.

A maioria dos coletores de lixo não permite que você obtenha uma lista de referências, portanto não ajudarão nesse caso.O Delphi pode fazer a contagem de referências se você usar interfaces, mas, novamente, você mesmo precisa acompanhar as referências.

Outras dicas

Não consigo entender por que você quer fazer isso.Certamente você apenas verificaria uma referência em não Nil antes de usá-la?

De qualquer forma, duas soluções possíveis que eu consideraria são:

  1. Faça com que os objetos gerenciem suas próprias contagens de referência.
  2. Crie uma classe de gerenciador de contagem de referência.

Eu provavelmente adicionaria as funções AddRef() e ReleaseRef() ao gerenciador ou à classe com reconhecimento de referência.Você pode então usá-los para verificar quantas referências existem em qualquer ponto.COM faz assim.

A classe com reconhecimento de referência gerenciaria apenas sua própria contagem de referências.O gerente poderia usar um Mapa para associar ponteiros a um número inteiro para contagem.

Você está tentando controlar quem está fazendo referência a um objeto para poder limpar essas referências quando o objeto for destruído ou está tentando controlar quando é seguro destruir o objeto?

Neste último caso, parece que você está procurando um coletor de lixo.Eu nunca lidei com Delphi, então não sei se existem GCs que você possa usar, mas ficaria surpreso se não existissem.

Se fosse o primeiro, um GC provavelmente não ajudaria.Se o Delphi suportar OOP/herança (sinceramente não sei se suporta), você poderia fazer algo assim (pseudocódigo):

// Anything that will use one of your tracked objects implements this interface
interface ITrackedObjectUser {
  public void objectDestroyed(TrackedObject o);
}

// All objects you want to track extends this class
class TrackedObject {
  private List<ITrackedObjectUser> users;

  public void registerRef(ITrackedObjectUser u) {
    users.add(u);
  }

  public void destroy() {
    foreach(ITrackedObjectUser u in users) {
      u.objectDestroyed(this);
    }
  }
}

Basicamente, sempre que você adiciona um de seus objetos rastreados a uma coleção, essa coleção se registra nesse objeto.Quando o objeto está sendo destruído (acho que você chamaria destroy() no destruidor do objeto), o objeto sinaliza à coleção que está sendo destruído para que a coleção possa fazer o que for necessário.

Infelizmente, esta não é realmente uma boa solução se você quiser usar coleções integradas.Você teria que escrever seus próprios objetos de coleção (eles poderiam apenas agrupar os integrados).E seria necessário ter certeza de que você está se registrando em todos os lugares onde deseja rastrear o objeto.Não é o que eu consideraria uma solução "feliz", embora para projetos pequenos provavelmente não fosse tão ruim.Espero principalmente que esta ideia ajude a gerar outras ideias.:)

Existe um motivo específico para você querer isso?Você está tendo problemas com dicas falsas ou está pensando que um dia isso pode ser um problema?

IMHO, não será um problema se você projetar seu aplicativo corretamente, e usar os padrões apropriados realmente ajuda você.

Algumas informações sobre padrões:

http://delphi.about.com/od/oopindelphi/a/aa010201a.htm

http://www.obsof.com/delphi_tips/pattern.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top