Подтвердить что ты не робот

Интерфейс Delphi не подсчитывается

Читая книгу экспертов Delphi, я нашел то, что не могу понять. Автор создал блок с этим кодом:

 IToDoData = interface //CRUD
    function ToDoCreate(aValue: TToDo): integer;
    function ToDoRead(id: integer; out aValue: TToDo): boolean;
    function ToDoUpdate(aValue: TToDo): boolean;
    function ToDoDelete(id: integer): boolean;
    procedure ToDoList(aList: TToDos);
  end;

Затем он решил использовать DataModule и реализовать описанный выше интерфейс таким образом:

type
  TDMToDo = class(TDataModule, IToDoData)
    // ... other code ...
  public
    // IToDoData
    function ToDoCreate(aValue: TToDo): integer;
    function ToDoRead(id: integer; out aValue: TToDo): boolean;
    function ToDoUpdate(aValue: TToDo): boolean;
    function ToDoDelete(id: integer): boolean;
    procedure ToDoList(aList: TToDos);
  end;

До сих пор так хорошо, но обратите внимание, что он не не поставил TInterfacedObject, поэтому здесь у нас нет таких методов, как AddRef и т.д. Я предполагаю, что вышеупомянутый код в порядке, но он должен быть включен в блок try... finally.

В основной форме (модуль модуля данных - это разделы использования, конечно) существует такая функция:

function TFormToDo.GetToDoData: IToDoData;
begin
  if DMToDo = nil then
    DMToDo := TDMToDo.Create(Application);
  Result := DMToDo;
end;

Приведенный выше код позволяет написать такой код:

begin
  GetToDoData.ToDoList(FToDos);

  ListView1.BeginUpdate;
  try
    //populate the list
  finally
    ListView1.EndUpdate;
  end;
end;

Не вызывает ли утечка памяти? По крайней мере, на окнах. Я новичок в delphi, поэтому я могу потерпеть неудачу, но я читал онлайн, что Android и IO имеют ARC, поэтому не нужно беспокоиться о попытке в конце концов.

У Windows нет ARC, поэтому я должен использовать try.. наконец, если не существует такой реализации, как TInterfacedObject (здесь нет). Так это ошибка?


Приложение представляет собой приложение ToDo, в котором вы пишете/читаете/сохраняете заметки. Модуль данных имеет компоненты доступа FireDAC, а методы интерфейса используются для доступа к db. Это должно поддерживать разделение между UI и db.

4b9b3361

Ответ 1

TDataModule является потоком TComponent, а TComponent реализует IInterface и связанные методы подсчета ссылок

  TComponent = class(TPersistent, IInterface, IInterfaceComponentReference)

Однако TComponent отключен подсчет ссылок, а компоненты управляются либо вручную, либо через модель собственности на компиляторе, отличном от ARC.

Чтобы быть более точным, TComponent отключил подсчет ссылок, если он не служит в качестве оболочки для объекта Windows COM. Это не так.

В компиляторе ARC есть небольшое осложнение с ручным управлением - фактически автоматическое управление, потому что, если вы не разрешаете TComponent потомкам управлять через собственность, их нужно освободить с помощью DisposeOf.

TComponent поведение отличается от поведения TInterfacedObject относительно подсчета ссылок на классический компилятор.

В приведенном выше случае утечки нет, потому что Application владеет этим модулем данных, и он будет управлять временем жизни модуля данных соответствующим образом для всех компиляторов.


try... finally блок не предназначен для управления памятью, но для защиты BeginUpdate... EndUpdate Вы должны оставить try...finally для всех компиляторов.