Форум: "KOL";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];
Внизdestructor Destroy; (освобождение ресурсов) Найти похожие ветки
← →
mdw (2003-05-12 11:55) [0]Давно возник этот вопрос, но както было не до того. Вопрос по поводу освобождения ресурсов. То ли я что-то, где-то не дочитал, то ли одно из двух...
При создании не визуального KOL компонента от TObj, определяем:
destructor Destroy; virtual; в нем помещаем код для освобождения ресурсов выделяемых компонентом, и все хорошо, и все работает.
При создании визуального KOL компонента от TControl, деструктор не вызывается никогда (по крайней мере у меня). Отсюда вопросы.
1. Почему? Что я не так делаю?
2. Если не в деструкторе, то где нужно освобождать выделяемые компонентом ресурсы?
Вариант: использовать Add2AutoFree, Add2AutoFreeEx. Правильно ли это? И почему все-таки не вызывается Destroy?
← →
BaRToV (2003-05-12 12:38) [1]> При создании визуального KOL компонента от TControl, деструктор не вызывается никогда (по крайней мере у меня).
Как говорил Кладов - деструктор лучше НЕ трогать у TControl, а лучше делать очитску данных так:
var
FBAPDriveBoxs: PList;
(* ДАННЫЕ ДЛЯ НАШЕГО ОБЪЕКТА *)
type
PDriveData = ^TDriveData;
TDriveData = object(TObj)
FControl: PControl;
...
destructor Destroy; virtual;
end;
(* Destructor НАШИХ ДАННЫХ *)
destructor TDriveData.Destroy;
begin
Timer1.Enabled := False;
Free_And_Nil(Timer1);
Free_And_Nil(IL);
Free_And_Nil(VolList);
FBAPDriveBoxs.Remove(FControl);
if FBAPDriveBoxs.Count = 0 then
Free_And_Nil(FBAPDriveBoxs);
inherited;
end;
Обрати внимаение на FBAPDriveBoxs.Remove( FControl), а НЕ FBAPDriveBoxs.Remove( @Self);
function NewBAPDriveBox;
var
D: PDriveData;
begin
Result := PBAPDriveBox(NewCombobox(Sender, [coReadOnly, coOwnerDrawFixed]));
if FBAPDriveBoxs = nil then
( Result) [1] > При создании визуального KOL компонента от TControl, деструктор не вызывается никогда (по крайней мере у меня).
Как говорил Кладов - деструктор лучше НЕ трогать у TControl, а лучше делать очитску данных так:
var
FBAPDriveBoxs: PList;
(* ДАННЫЕ ДЛЯ НАШЕГО ОБЪЕКТА *)
type
PDriveData = ^TDriveData;
TDriveData = object(TObj)
FControl: PControl;
...
destructor Destroy; virtual;
end;
(* Destructor НАШИХ ДАННЫХ *)
destructor TDriveData.Destroy;
begin
Timer1.Enabled := False;
Free_And_Nil(Timer1);
Free_And_Nil(IL);
Free_And_Nil(VolList);
FBAPDriveBoxs.Remove(FControl);
if FBAPDriveBoxs.Count = 0 then
Free_And_Nil(FBAPDriveBoxs);
inherited;
end;
Обрати внимаение на FBAPDriveBoxs.Remove( FControl), а НЕ FBAPDriveBoxs.Remove( @Self);
function NewBAPDriveBox;
var
D: PDriveData;
begin
Result := PBAPDriveBox(NewCombobox(Sender, [coReadOnly, coOwnerDrawFixed]));
if FBAPDriveBoxs = nil then
FBAPDriveBoxs := NewList;
FBAPDriveBoxs.Add(Result);
New(D, Create);
Result.CustomObj := D;
D.FControl := Result;
...
end;
Посмотри:
http://bonanzas.rinet.ru/art003.htm
http://delphikol.narod.ru/docs/WritingComp.htm
← →
mdw (2003-05-12 14:04) [2]Спасибо. Разобрался. Пользовался CustomData, вместо CustomObj.
Только не понял что такое FBAPDriveBoxs.Remove(FControl)? Ни где не нашел, кроме Plist (в том числе и в BAPDriveBox).
Еще такой вопрос. При создании компонента добавляю обработчик при помощи AttachProc. Нужно ли при разрушении компонента отсоединять обработчик (DetachProc)? Наверное не принципиально, нет окна - некому и получать собщение, или как?
← →
Gandalf (2003-05-12 15:49) [3]
> Нужно ли при разрушении компонента отсоединять обработчик
> (DetachProc)? Наверное не принципиально, нет окна - некому
> и получать собщение, или как?
Так и есть. Не трать код.
← →
BaRToV (2003-05-12 16:05) [4]2 mdw ©
Подожди, щас все подробно опишу...
← →
BaRToV (2003-05-12 16:43) [5]2 Gandalf ©
Так и есть. Не трать код.
Так, смотри.
Если xxx.Free, то очистится атвтоматом, если мы не сделали так:
function NewBAPDriveBox;
...
begin
...
Result.AttachProc(WndProcDrive); // Само очистится...
if Applet <> nil then // А вот это освобождать НАДО!!!
Applet.AttachProc(WndProcDriveChange);
...
end;
destructor TDriveData.Destroy;
begin
...
FBAPDriveBoxs.Remove(FControl);
if FBAPDriveBoxs.Count = 0 then
begin
Free_And_Nil(FBAPDriveBoxs);
if (@WndProcDriveChange <> nil) and (Applet <> nil) then
Applet.DetachProc(WndProcDriveChange);
end;
inherited;
end;
Так как Applet жив, а компонент = nil, то КРАХ!!!
Поэтому если в компоненты используется Applet.AttachProc(xxx), то всегда нужно вызывать Applet.DetachProc(xxx), если компонет(ы) = nil.
2 mdw ©
> Только не понял что такое FBAPDriveBoxs.Remove(FControl)? Ни где не нашел, кроме Plist (в том числе и в BAPDriveBox).
var
FBAPDriveBoxs: PList; // Список с указателями на BAPDriveBox"ы
Для чего это нужно?
if Applet <> nil then
Applet.AttachProc(WndProcDriveChange);
Applet не знает сколько твоих компонентов на нем и чтобы обратиться к кажому из них или только к нужному, делаем так:
function WndProcDriveChange(Ctl: PControl; var Msg: TMsg;
var Rslt: Integer): Boolean;
var
...
D: PDriveData;
DB: PBAPDriveBox;
...
begin
Result := False;
if Msg.message = WM_DEVICECHANGE then
for Idx := 0 to FBAPDriveBoxs.Count - 1 do
begin
DB := FBAPDriveBoxs.Items[Idx];
D := Pointer(DB.CustomObj);
...
DB.UpdateDriveBox;
...
( Gandalf) [5]2 Gandalf ©
Так и есть. Не трать код.
Так, смотри.
Если xxx.Free, то очистится атвтоматом, если мы не сделали так:
function NewBAPDriveBox;
...
begin
...
Result.AttachProc(WndProcDrive); // Само очистится...
if Applet <> nil then // А вот это освобождать НАДО!!!
Applet.AttachProc(WndProcDriveChange);
...
end;
destructor TDriveData.Destroy;
begin
...
FBAPDriveBoxs.Remove(FControl);
if FBAPDriveBoxs.Count = 0 then
begin
Free_And_Nil(FBAPDriveBoxs);
if (@WndProcDriveChange <> nil) and (Applet <> nil) then
Applet.DetachProc(WndProcDriveChange);
end;
inherited;
end;
Так как Applet жив, а компонент = nil, то КРАХ!!!
Поэтому если в компоненты используется Applet.AttachProc(xxx), то всегда нужно вызывать Applet.DetachProc(xxx), если компонет(ы) = nil.
2 mdw ©
> Только не понял что такое FBAPDriveBoxs.Remove(FControl)? Ни где не нашел, кроме Plist (в том числе и в BAPDriveBox).
var
FBAPDriveBoxs: PList; // Список с указателями на BAPDriveBox"ы
Для чего это нужно?
if Applet <> nil then
Applet.AttachProc(WndProcDriveChange);
Applet не знает сколько твоих компонентов на нем и чтобы обратиться к кажому из них или только к нужному, делаем так:
function WndProcDriveChange(Ctl: PControl; var Msg: TMsg;
var Rslt: Integer): Boolean;
var
...
D: PDriveData;
DB: PBAPDriveBox;
...
begin
Result := False;
if Msg.message = WM_DEVICECHANGE then
for Idx := 0 to FBAPDriveBoxs.Count - 1 do
begin
DB := FBAPDriveBoxs.Items[Idx];
D := Pointer(DB.CustomObj);
...
DB.UpdateDriveBox;
...
end; // FOR
end;
Дим (Gandalf), может это в FAQ засунишь?!
← →
BaRToV (2003-05-12 17:00) [6]2 mdw
> Только не понял что такое FBAPDriveBoxs.Remove(FControl)?
Удаляет нужный указатель(элемент) из списка.
← →
mdw (2003-05-12 19:52) [7]Все понятно. Спасибо. Просто в BAPDriveBox случай частный, сперва не въехал о чем речь.
← →
Gandalf (2003-05-12 19:55) [8]
> Так как Applet жив, а компонент = nil, то КРАХ!!!
Это другой случай, а мы говороли о Wndproc которую пришили к мертвуму контролу - если нет контрола, нет и проблемм.
Т.е. если было Result.AttachProc(WndMyCrazyDoIt), то Detach не нужен.
> Дим (Gandalf), может это в FAQ засунишь?!
А что конкретно? Необходиться создания списка контролов при жедании обрабатывать сообщеине для всех (или контретного)? Или что (Attach/Detach)?
← →
BaRToV (2003-05-13 01:18) [9]2 Gandalf ©
Подумаю и по мылу отошлю...
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.007 c