Перейти к содержанию
Fire Monkey от А до Я

Вопрос по работе с классами


Рекомендуемые сообщения

Доброго дня.
Возник небольшой вопрос при создании классов.
Выдержка из кода:

//объявление классов

TFileInfo = class
  private
    ...
FSize: Int64;
  Public
    ...
property Size: Int64 read FSize write FSize;
    procedure Free;
    ...
  end;
 

TListFile<T: TFileInfo> = class(TObjectList<T>)
  private
...
function GetAllSize: Int64;
  public
    ...
property AllSize: Int64 read GetAllSize;
    procedure Clear; overload;
    ...
  end;

// реализация классов
...
 
procedure TFileInfo.Free;
begin
  if Self <> nil then
    Destroy;
end;
 
...
 

function TListFile<T>.GetAllSize: Int64;
var
  i: integer;
begin
  Result := 0;
  for i := 0 to Count - 1 do
    Result := Result + Items[i].Size;
end;

...
procedure TListFile<T>.Clear; 
var 
  i: integer; 
begin 
  for i := 0 to Count - 1 do 
    Items[i].Free; 
  inherited Clear; 
end;

В общем IDE в секции "Structure" выдает ошибки "Undeclared identifier 'Free'('Size') at line №строки в процедуре Clear и GetAllSize
Сам код не смотря на выдаваемые ошибки компилируются без Hints и Warnings
Ткните меня плиз в мое не совершенство.

 

P.S.

Выкрутился таким путем

...
function TListFile<T>.GetAllSize: Int64;
var
  tb: T;
begin
  Result:=0;
  for tb in List do
    if tb <> nil then
      Result := Result + tb.Size;
end;
...
procedure TListFile<T>.Clear;
var
  tb: T;
begin
  for tb in List do
    if tb <> nil then
      tb.Free;
  inherited Clear;
end;

Подскажите верно ли я поступил?

Изменено пользователем Николай Ряполов
Ссылка на комментарий
  • Администраторы

Добрый день,

 

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

 

P.S. Однако в вашем коде:

  1. Совершенно лишняя реализация метода Clear. Если при создании вашего TObjectList в конуструкторе указать AOwnsObjects = True. То метод Clear из TList<> удалить и распустит ваши элементы.
  2. Совершенно лишняя реализация метода Free. Этот метод базовый и присутствует во всех класса, так как он введен на уровне TObject.
Ссылка на комментарий

Добрый день,

 

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

 

P.S. Однако в вашем коде:

  • Совершенно лишняя реализация метода Clear. Если при создании вашего TObjectList в конуструкторе указать AOwnsObjects = True. То метод Clear из TList<> удалить и распустит ваши элементы.
  • Совершенно лишняя реализация метода Free. Этот метод базовый и присутствует во всех класса, так как он введен на уровне TObject.

Изначально мой класс базировался на TList<T>, но по ряду причин после обработки 500к файлов память забивалась до 150 Мб, и методом TList.Free не освобождалась. Изменил базовый класс на TObjectList , память этим методом TObjectList.Free очищается полностью (100 итераций заполнение - очистка списка).

Если я Вас верно понял то в описании класса достаточно описать так:

TListFile<T: TFileInfo> = class(TObjectList<T>)
  private
    ...
    AOwnsObjects = True;
    ... 
    function GetAllSize: Int64;
  public
    ...
    property AllSize: Int64 read GetAllSize;
    // procedure Clear; overload; //тут можно удалить процедуру
    ...
  end;

Или требуется сделать так:

TListFile<T: TFileInfo> = class(TObjectList<T>)
  private
    ... 
    function GetAllSize: Int64;
  public
    ...
    property AllSize: Int64 read GetAllSize;
    constructor Create; overload;
    // procedure Clear; overload; //тут можно удалить процедуру
    ...
  end;

...
  constructor TListFile<T>.Create;
  begin
    inherited create;
    AOwnsObjects = True;
  end;
...

Если Вас не затруднит еще один небольшой вопрос.

Столкнулся со сравнением двух списков TListObject<T>, где Т: class содержащий информацию о файлах.

Сравнивать как списки как:

 for T in ObjectList1 do
   if ObjectList2.IndexOf(T)>0 then
     // тут код сравнения

однозначно позволяет установить что именно class 'T' в ObjectList1 точно соответствует class 'T' в ObjectList2. Так как отсутствие class 'Т' из ObjectList1 или малейшее его изменение в списке ObjectList2 однозначно требует проверки на внутреннюю проверку списков методом:

var
  isModif: Boolean;
begin
...

for T1 in ObjectList1 do
begin
  isModif := False;
  for T2 in ObjectList2 do
  begin
    if T1.Name = T2.Name then
    begin

      if (T1.Size <> T2.Size) or (T1.ModDate <> T2.ModDate) then
        T1.Status := fiModif // const fiModif = $00000001 
      else
        T1.Status := fiNoModif; // const fiNoNodif = $00000002

      isModif := True;
    end;
    if not isModif then
      T1.Status := fiCreate; // const fiCreate = $00000004
  end;
end;     

Если этот же класс реализовать через  TDictonary добавив в TKey T1.Name  и уже сравнение проводить согласно вхождению файлов в список ObjectList2 скорость сравнения достаточно увеличится или можно пренебречь реализацией?

Изменено пользователем Николай Ряполов
Ссылка на комментарий
  • Администраторы
  1. TList не освоождает память своих элементов. А вот, если вы хотите, чтобы оъекты-элементы тоже удалялись и есть TObjectList. Но освобождать память под объекты или нет, зависит от значения параметра AOwnedObject при создании списка.
  2. Да
Ссылка на комментарий

 

  1. TList не освобождает память своих элементов. А вот, если вы хотите, чтобы объекты-элементы тоже удалялись и есть TObjectList. Но освобождать память под объекты или нет, зависит от значения параметра AOwnedObject при создании списка.
  2. Да

 

Таким образом подытожим выше сказанное:

1. класс создаем таким образом:

var
  LF: TListFile<T>;
begin
  ...
  LF:= TListFile<T>.Create(True); //так мы говорим что надобно освобождать память автоматически
  try
    ...
    //тут работаем с нашим кодом
    ...
  finally
    LF.Free; //корректно подчищает за собой при установленном флаге AOwnerObject
  end;

end

Сам класс для хранения объектов меняем с TObjectList на TDictonary для увеличения производительности при сортировке массивов ввиду уже заложенных в "Словарь" алгоритмов на уровне системы.

Спасибо огромное!

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...