Как отслеживать ссылки на объект?

В мире, где по-прежнему правят ручное выделение памяти и указатели (Borland Delphi), мне нужно общее решение для того, что я считаю общей проблемой:

В данный момент на объект можно ссылаться из нескольких мест (списки, другие объекты, ...). Есть ли хороший способ отслеживать все эти ссылки, чтобы я мог обновлять их при уничтожении объекта? В


person Community    schedule 20.08.2008    source источник


Ответы (4)


Если вы хотите уведомить других об изменениях, вам следует реализовать "Шаблон наблюдателя". Delphi уже сделала это за вас для потомков TComponent. Вы можете вызвать метод TComponent.FreeNotification и получить уведомление об уничтожении другого компонента. Он делает это, вызывая метод Notification. Вы можете удалить себя из списка уведомлений, вызвав TComponent.RemoveFreeNotification. См. также эту страницу.

Большинство сборщиков мусора не позволяют получить список ссылок, поэтому в данном случае они не помогут. Delphi может выполнять подсчет ссылок, если вы будете использовать интерфейсы, но опять же вам придется отслеживать ссылки самостоятельно.

person Lars Truijens    schedule 20.08.2008

Я не могу понять, почему вы хотите это сделать. Конечно, вы бы просто проверили ссылку не в Nil перед ее использованием?

Anwyays, я бы рассмотрел два возможных решения:

  1. У менеджера объектов есть свои собственные счетчики ссылок.
  2. Создайте класс менеджера подсчета ссылок.

Вероятно, я бы добавил функции AddRef() и ReleaseRef() либо к менеджеру, либо к классу, поддерживающему ссылки. Затем вы можете использовать их, чтобы проверить, сколько ссылок существует в любой момент. COM делает это таким образом.

Класс, поддерживающий ссылки, будет управлять только своим собственным счетчиком ссылок. Менеджер может использовать карту, чтобы связать указатели с целым числом для подсчета.

person Steve    schedule 20.08.2008
comment
+1 за вторую идею, создание подкласса TInterfacedObject (или создание аналогичного ему корневого класса) было бы простым способом создания класса менеджера подсчета ссылок. - person mjn; 10.11.2010

Вы пытаетесь отслеживать, кто ссылается на объект, чтобы вы могли очистить эти ссылки, когда объект уничтожается, или вы пытаетесь отслеживать, когда можно безопасно уничтожить объект?

Если последнее, то похоже, что вы ищете сборщик мусора. Я никогда не имел дело с Delphi, поэтому я не знаю, есть ли для него GC, которые вы можете использовать, но я был бы удивлен, если бы их не было.

Если первое, то GC, вероятно, не поможет. Если Delphi поддерживает ООП/наследование (честно говоря, я не знаю, поддерживает ли это), вы можете сделать что-то вроде этого (псевдокод):

// 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);
    }
  }
}

По сути, всякий раз, когда вы добавляете один из ваших отслеживаемых объектов в коллекцию, эта коллекция будет регистрироваться с этим объектом. Когда объект уничтожается (я полагаю, вы бы вызвали destroy() в деструкторе объекта), тогда объект сообщает коллекции, что он уничтожается, поэтому коллекция может делать все, что ей нужно.

К сожалению, это не очень хорошее решение, если вы хотите использовать встроенные коллекции. Вам придется написать свои собственные объекты коллекции (хотя они могут просто обернуть встроенные объекты). И это потребует убедиться, что вы регистрируетесь везде, где хотите отслеживать объект. Это не то, что я бы назвал «счастливым» решением, хотя для небольших проектов это, вероятно, было бы не так уж плохо. Я в основном надеюсь, что эта идея поможет породить другие идеи. :)

person Herms    schedule 20.08.2008

Есть ли конкретная причина, по которой вы этого хотите? Сталкиваетесь ли вы с проблемами с мошенническими указателями или думаете, что однажды это может стать проблемой?

ИМХО, это не будет проблемой, если вы правильно спроектируете свое приложение, и использование соответствующих шаблонов действительно поможет вам.

Немного информации о паттернах:

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

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

person Ferry van Genderen    schedule 06.11.2008