Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.48 MB
Время: 0.008 c
3-93343
YuRock
2004-01-04 17:56
2004.01.29
BDE... Где взять?


4-93744
Sergei
2003-11-22 11:29
2004.01.29
StdIn и StdOut


14-93642
Ig
2004-01-08 15:07
2004.01.29
Как поместить форму под значки на рабочем столе


3-93366
Danilas
2004-01-02 20:11
2004.01.29
Как запустить процедуру в Interbase с помошью Делфи


14-93640
Семен Сорокин
2004-01-08 15:43
2004.01.29
MapObjects





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский