Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.12.16;
Скачать: [xml.tar.bz2];

Вниз

FreeAndNil и метод Free у классов от TWinControl.   Найти похожие ветки 

 
Maks Realov   (2003-12-05 11:51) [0]

Всем здрямс.
Есть вопрос. Для освобождения ресурсов из под экземпляров своих классов, порождённых от TObject, использовал функцию FreeAndNil, её реализация проста как мычание, но сама функция удобна.
Так вот, а если я создаю форму из некой процедуры и делаю ей Show и теряю указатель на эту форму после выхода из данной процедуры, а в событии OnClose этой формы вызываю FreeAndNil(self), то данная функция отрабатывает как надо? По идее все контролы удаляемой формы корректно должны освобождаться при Free самой формы.
Объясните, есть ли отличие в следующих способах освобождения ресурсов из под формы при её OnClose, и какие:

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
1). FreeAndNil(self);
2). Self.Free; // освобождаем
Self:= nil;// обнуляем ссылку
3). Self.Release; //ждём пока отработает вся цепочка сообщений, пока всё освободиться и потом уничтожаем форму и чистим аллокируюмую память - предпочтительно это по help"у.
4). Action:= caFree; // тоже делает Release - см. код TCustomForm.Close;
end;

Так почему не рекомендуют делать FreeAndNil или просто Free из методов формы, которую удаляем?


 
Skier   (2003-12-05 11:53) [1]

Вариант 4) самое то !
И не надо ничего здесь выдумывать - не тот случай...


 
Digitman   (2003-12-05 11:53) [2]

правилен и корректен лишь способ №4


 
NikeOLD   (2003-12-05 11:58) [3]


> Так почему не рекомендуют делать FreeAndNil или просто Free
> из методов формы, которую удаляем?

Пробовал это делать? Access violation... получал?


 
Бушин Сергей   (2003-12-05 12:02) [4]

Потому как ты уничтожаешь форму в методе, который принадлежит самой форме.


 
NikeOLD   (2003-12-05 12:04) [5]

Нельзя вызывать метод Free объекта из других процедур и функций объекта. Хочешь выпендриться, то посылай WM_DESTROY своей форме из OnClose.

А вообще задача-то какова? Динамическое создание формы? Тогда создавай отдельную процедуру в модуле с твоей формой (не метод этой формы). В ней сначала делай Create форме, затем в блоке try..finally вызывай Show в блоке finally..end делай Free самой форме, нужен код - пиши на мыло, я здесь не часто бываю.


 
Maks Realov   (2003-12-05 12:04) [6]

Всё пробовал.
AV получал только если дальше пробовал что-либо делать, после Free.

Народ, спасибо конечно, что сказали КАК надо - благодарен, но лучше бы вы объяснили ПОЧЕМУ.

И ещё. Как мне в коде проверять на наличие экземпляра формы перед её созданием?
Ведь Assign проверяет на не nil ссылки, а после освобождения через Free и Release ссылка не обнуляется.


 
Dimka Maslov   (2003-12-05 12:06) [7]

Прочитай про то как организована форма, и что такое OnClose


 
Digitman   (2003-12-05 12:08) [8]


> Бушин Сергей


здесь ты неправ
метод-диструктор TSomeForm.Destroy есть такой же метод объекта-формы, как и прочие методы, однако в вызове SomeForm.Destroy нет ничего архикриминального

здесь проблема в другом - в неявной попытке обращения к полям только что разрушенного (уже несуществующего) экз-ра класса уже ПОСЛЕ завершения обработчика указанного события


 
Skier   (2003-12-05 12:10) [9]


> а после освобождения через Free и Release ссылка не обнуляется.


procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Form2 := nil;
Action:= caFree;
end;


 
Digitman   (2003-12-05 12:12) [10]


> Maks Realov


> Как мне в коде проверять на наличие экземпляра формы перед
> её созданием


ссылку-то не теряй ! и проверять ничего не нужно будет)
после вызова FreeAndNil(SomeForm) переменная-ссылка SomeForm станет равной nil, и последующая проверка на банальный Assigned() даст 100%-ю гарантию, что объект-форма в момент проверки не существует


 
Maks Realov   (2003-12-05 12:13) [11]

2 Digitman:
Поправь, если я ошибаюсь:
OnCreate возникает, когда форма уже создана.
OnClose возникает, когда форма ещё не разрушена, т.е. перед выполнением Destroy.
Если это так, то где тут обращение к полям разрущенной уже формы?
Или я что-то не понимаю? ;)


 
Maks Realov   (2003-12-05 12:16) [12]

2 Digitman © (05.12.03 12:12):
ты наверное не понял, ЧТО я имелл ввиду, или я криво сказал.
Есть метод в котором создаётся форма. Перед её созданием, надо проверить - нет ли уже одного экземпляра этой формы.

Вроде, Skier © (05.12.03 12:10) - то что надо.


 
Maks Realov   (2003-12-05 12:21) [13]

Во, вроде такой изврат работает как надо:

unit Unit1;

interface

uses
...
Dialogs, StdCtrls, Unit2;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Form2: TForm2;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
if not(Assigned(Form2)) then
begin
Form2:= TForm2.Create(Application);
Form2.Show;
end;
end;
end.

//**************************//
unit Unit2;

interface

uses
...

type
TForm2 = class(TForm)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Form1.Form2:= nil;
Action:= caFree;
end;
end.


Изврат?


 
NikeOLD   (2003-12-05 12:21) [14]

Господа, уточните все-таки задачу.


 
Digitman   (2003-12-05 12:26) [15]


> Maks Realov


вот смотри что происходит
фрагмент исходников :



procedure TCustomForm.Close;
var
CloseAction: TCloseAction;
begin
if fsModal in FFormState then
ModalResult := mrCancel
else
if CloseQuery then
begin
if FormStyle = fsMDIChild then
if biMinimize in BorderIcons then
CloseAction := caMinimize else
CloseAction := caNone
else
CloseAction := caHide;
DoClose(CloseAction); // здесь вызывается обработчик OnClose и в нем ты уничтожаешь тек.экз-р
if CloseAction <> caNone then
if Application.MainForm = Self then Application.Terminate
else if CloseAction = caHide then Hide //здесь - засада
else if CloseAction = caMinimize then WindowState := wsMinimized // и здесь - засада
else Release; //и здесь - засада
end;
end;

procedure TCustomForm.Release;
begin
PostMessage(Handle, CM_RELEASE, 0, 0);
end;



 
Anatoly Podgoretsky   (2003-12-05 12:31) [16]

Maks Realov (05.12.03 12:16) [12]
Все созданые формы хранятся в Screen.Forms, никакой нет нужды в допольнительных переменных, кроме удобства конечно.


 
HSolo   (2003-12-05 12:32) [17]

> Есть метод в котором создаётся форма. Перед её созданием, надо проверить - нет ли уже одного экземпляра этой формы.

Ищите ее в Screen.Forms


 
Maks Realov   (2003-12-05 13:11) [18]

Во! Спасибо! Screen.Forms - то что надо в данном случае ;)

2 Digitman © (05.12.03 12:26):

Угу, спасибо, понял.
Хех, сам этот код просматривал несколько раз, а в таком ключе не воспринимал.
Ну на то вы и Мастера ;)



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.12.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.008 c
1-52158
sowell
2003-12-03 16:45
2003.12.16
DBCtrlGrid и его панели


3-52111
_sulent
2003-11-24 09:52
2003.12.16
подскажите как можно сделать...


1-52197
LittleGirly
2003-12-05 15:35
2003.12.16
Вопрос по TreeView


14-52395
REP
2003-11-20 15:04
2003.12.16
День налогового инспектора.


3-52067
Pako
2003-11-24 08:29
2003.12.16
Error creating cursor handle





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский