Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.01.29;
Скачать: CL | DM;

Вниз

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 вся ветка

Текущий архив: 2004.01.29;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.012 c
3-93400
smu
2003-12-30 09:49
2004.01.29
DBGrid Контроль ввода данных.


14-93625
Карелин Артем
2004-01-08 15:32
2004.01.29
Басик-> Дельфи или Басик-> Си. Где найти прогу для перевода?


3-93399
Silver_
2003-12-30 11:17
2004.01.29
Fast Report - Проверка на NULL (в скрипте)


1-93428
_none_
2004-01-16 15:29
2004.01.29
вывод графики через bitblt: мелькание (синхронизация?)


3-93342
dimablind
2004-01-03 19:10
2004.01.29
locate