Форум: "Прочее";
Текущий архив: 2006.08.27;
Скачать: [xml.tar.bz2];
Вниз"Правильное" уничтожение фреймов при работе с TTreeView Найти похожие ветки
← →
Loginov Dmitry © (2006-07-29 21:23) [0]Вот наткнулся сегодня на проблему "правильного" уничтожения фреймов.
На фрейме у меня лежит TTreeView, и элементы добавляются динамически. У фрейма есть деструктор. Вот его код:
destructor TFrame2.Destroy;
begin
MessageBox(0, PChar(IntToStr(TreeView1.Items.Count)),"",0);
inherited;
end;
И что вы думаете? MessageBox показывает, что количество элементов дерева равно нулю (не важно, сколько их там было фактически). Фрейм кладется на форму в Design-Time (к слову). Похоже, что элементы дерева удаляются каким-то образом еще до вызова Destroy.
Баг этот я считаю достаточно серьезным, и он может привести к ощутимым утечкам памяти. Например, вы в TTreeNode храните ссылки на динамически создаваемые данные. И надеетесь, что они удаляются в Destroy. А фигушки!
Я предлагаю следующий выход:destructor TForm1.Destroy;
var
I: Integer;
begin
for I := 0 to ComponentCount - 1 do
if Components[I] is TFrame then
Components[I].Free;
inherited;
end;
где TForm1 - форма, на которой лежит фрейм.
← →
Piter © (2006-07-29 21:27) [1]я не понял. Если я храню элементы в TTreeNode - то я буду удалять их при TTreeView.OnDeletion.
С чего ты взял, что к моменту TForm.OnDestroy ее дочерние компоненты НЕ должны быть уничтожены?
Не засчитывается, я видал баги и посерьезнее :)
← →
Loginov Dmitry © (2006-07-29 21:30) [2]> то я буду удалять их при TTreeView.OnDeletion
Не самый удобное место для этого.
> С чего ты взял, что к моменту TForm.OnDestroy ее дочерние
> компоненты НЕ должны быть уничтожены
А где было написано, что я что-то с чего-то взял?
← →
Loginov Dmitry © (2006-07-29 21:33) [3]> Не самой удобное место для этого.
Это я к тому, что возникнут проблемы с Drag & Drop.
← →
DiamondShark © (2006-07-29 23:36) [4]TFrame2 = class(TFrame)
TreeView1: TTreeView;
procedure TreeView1Deletion(Sender: TObject; Node: TTreeNode);
private
procedure WMDestroy(var M: TMessage); message WM_DESTROY;
public
destructor Destroy; override;
end;
destructor TFrame2.Destroy;
begin
inherited;
end;
procedure TFrame2.WMDestroy(var M: TMessage);
begin
inherited;
end;
ставим брякпоинты в деструкторе и обработчике.
запускаем.
закрываем форму "крестиком".
попадаем сначала в WMDestroy, потом в destructor.
Запускаем ещё раз.
Выполняем
Frame21.Free;
попадаем сначала в destructor, потом в WMDestroy.
Вообще-то, как и ожидалось.
Ну а уж то, что в ответ на WM_DESTROY тривью удаляет итемы -- не баг, а фича.
;)
← →
Loginov Dmitry © (2006-07-30 09:49) [5]> Ну а уж то, что в ответ на WM_DESTROY тривью удаляет итемы
> -- не баг, а фича
Да за такие фичи да голову бы оторвать. Два часа убил на то, чтобы отыскать, где же источник утечки памяти. А это фича. Вот как!
;)
← →
Юрий Зотов © (2006-07-30 12:02) [6]Осталось только выяснить, чья это фича - Win32 или VCL.
← →
jack128 © (2006-07-30 14:16) [7]Юрий Зотов © (30.07.06 12:02) [6]
Осталось только выяснить, чья это фича - Win32 или VCL.
VCL"евская, очевидно. Автоматом следует из разделения понятий TWinControl и окно Windows.
← →
DiamondShark © (2006-07-30 14:40) [8]
> Автоматом следует из разделения понятий TWinControl и окно
> Windows.
Вовсе даже не автоматом.
"Плотность прилегания" компонентной обёртки и системных объектов обеспечить можно, вопрос в затратах. В худшем случае -- вплоть до полного дублирования.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2006.08.27;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.057 c