Форум: "Основная";
Текущий архив: 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.009 c