Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Управление жизненным циклом объектов в Delphi: особенности использования интерфейсов и подсчета ссылок

Delphi , Программа и Интерфейс , Интерфейс

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

Пример, демонстрирующий проблему:

program SO16210993;
{$APPTYPE CONSOLE}

type
  IFoo = interface
    procedure Foo;
  end;

  TFooImpl = class(TInterfacedObject, IFoo)
    procedure Foo;
  end;

  TContainer = class(TInterfacedObject, IFoo)
  private
    FFoo: IFoo;
  public
    constructor Create;
    destructor Destroy; override;
    property Foo: IFoo read FFoo implements IFoo;
  end;

procedure TFooImpl.Foo;
begin
  Writeln('TFooImpl.Foo called');
end;

constructor TContainer.Create;
begin
  inherited;
  FFoo := TFooImpl.Create;
end;

destructor TContainer.Destroy;
begin
  Writeln('TContainer.Destroy called');// Эта строка никогда не выполняется
  inherited;
end;

procedure Main;
var
  Foo : IFoo;
begin
  Foo := TContainer.Create;
  Foo.Foo;
end;

begin
  Main;
  Readln;
end.

Если вместо использования implements реализовать интерфейс в классе TImplementor, то destructor объекта будет вызван.

Объяснение проблемы:

Проблема заключается в том, что при создании объекта TContainer и последующем присваивании ссылки на него переменной интерфейса Foo, реализующим объектом становится экземпляр TFooImpl, а не TContainer. Таким образом, ссылка на TContainer не увеличивается, и объект никогда не уничтожается.

Решение проблемы:

Для решения проблемы можно использовать класс TAggregatedObject, который позволяет агрегируемому объекту делиться жизненным циклом с агрегирующим объектом. Вот пример кода, использующего TAggregatedObject:

program SO16210993_TAggregatedObject;
{$APPTYPE CONSOLE}

type
  IFoo = interface
    procedure Foo;
  end;

  TFooImpl = class(TInterfacedObject, IFoo)
    procedure Foo;
  end;

  TContainer = class(TInterfacedObject, IFoo)
  private
    FFoo: TFooImpl;
    function GetFoo: IFoo;
  public
    destructor Destroy; override;
    property Foo: IFoo read GetFoo implements IFoo;
  end;

procedure TFooImpl.Foo;
begin
  Writeln('TFooImpl.Foo called');
end;

destructor TContainer.Destroy;
begin
  Writeln('TContainer.Destroy called');// Эта строка теперь выполняется
  FFoo.Free;
  inherited;
end;

function TContainer.GetFoo: IFoo;
begin
  if not Assigned(FFoo) then
    FFoo := TFooImpl.Create(Self);
  Result := FFoo;
end;

procedure Main;
var
  Foo : IFoo;
begin
  Foo := TContainer.Create;
  Foo.Foo;
end;

begin
  Main;
  Readln;
end.

Использование TAggregatedObject позволяет агрегируемому объекту FFoo делить жизненный цикл с TContainer, что и приводит к вызову destructor объекта TContainer.

Заключение:

При работе с интерфейсами в Delphi важно понимать, как работает подсчет ссылок и как он влияет на жизненный цикл объектов. В случае использования агрегирования объектов через интерфейсы, следует применять класс TAggregatedObject для корректного управления жизненным циклом объектов.

Создано по материалам из источника по ссылке.

Контекст описывает проблему связанную с управлением жизненным циклом объектов в Delphi, когда при агрегировании объекта через интерфейс не происходит корректный подсчет ссылок и вызов деструктора.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Интерфейс ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 15:03:51/0.0052850246429443/1