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

Вниз

Уничтожение объекта   Найти похожие ветки 

 
faiwer ©   (2010-09-30 18:30) [0]

Доброго времени суток. Я всё никак не могу понять принцип уничтожения чего-либо в Delphi (особенно если речь идёт о нитях). Вот и сейчас...

 a:=TSome.Create(...);
 a.Free;
 ...
 if a<>nil
   then a.Free;


Почему после a.Free a не nil? Каким образом следует уничтожать экземпляры класса? Если через Free, то как потом проверить уничтожен объект или нет?


 
Palladin ©   (2010-09-30 18:37) [1]

а - это переменная, а не объект. ни один объект не знает о том в какой и в скольких и в каком потоке на него есть переменная. согласен?


 
faiwer ©   (2010-09-30 18:42) [2]

Кажется понял, получается надо так?

> a:=TSome.Create(...);
> a.Free;
> a:=nil;
> ...
> if a<>nil
>   then a.Free;


 
Palladin ©   (2010-09-30 18:48) [3]

да, и, что-бы не писать две строки, придумали гениальную процедуру - FreeAndNil


 
0x00FF00 ©   (2010-09-30 18:51) [4]

Ну, есть ещё FreeAndNIL.
Не знаю, правда, насколько правомерно его использование для освобождения объектов, т.к. сам освобождал с его помощью только память, GetMem"ом полученную.

http://www.delphisources.ru/pages/faq/faq_delphi_basics/FreeAndNil.php.html
Тут, в частности, сказано, что попытка освобождения NIL"а проходит "чисто", т.е. вызов просто ничего не сделает.


 
0x00FF00 ©   (2010-09-30 18:52) [5]

Блин. Не успел =(


 
_Юрий   (2010-09-30 19:14) [6]


>  if a<>nil
>    then a.Free;


проверка на nil лишняя, она проводится внутри самого Free, см. System.pas:

procedure TObject.Free;
begin
 if Self <> nil then
  Destroy;
end;

Кстати, если объект создается и разрушается по схеме
MyObj:=TMyObj.Create;
try
 MyObj.SomeMethod;
finally
 MyObj.Free;
end;

то по большому счету использование именно Free - не более чем дань обычаю, в данном случае он не может быть nil-ом в принципе, таким образом имеем лишнюю проверку.
Но так принято.


 
faiwer ©   (2010-09-30 19:18) [7]

Теперь разобрался, всем спасибо.


 
Anatoly Podgoretsky ©   (2010-09-30 19:31) [8]


> faiwer ©   (30.09.10 18:42) [2]

Так не надо.


 
Anatoly Podgoretsky ©   (2010-09-30 19:33) [9]


> Palladin ©   (30.09.10 18:48) [3]

Для этого не надо использовать эту уродскую процедуру, а надо написать свою FreeEx(var A: TObject)


 
Anatoly Podgoretsky ©   (2010-09-30 19:35) [10]


> 0x00FF00 ©   (30.09.10 18:51) [4]
> Ну, есть ещё FreeAndNIL.
> Не знаю, правда, насколько правомерно его использование
> для освобождения объектов, т.к. сам освобождал с его помощью
> только память, GetMem"ом полученную.

Ты шутишь? Применять Free к указателю. Правда эту она способствует, поскольку происходит потеря типизации, в этом ее сильный недостаток.
Должно возникать исключение.


 
Anatoly Podgoretsky ©   (2010-09-30 19:39) [11]


> _Юрий   (30.09.10 19:14) [6]

Только для классики TMyObj должен быть локальной или полностью отсутствовать, классика когда

with TMyObj.Create do
try
 SomeMethod;
finally
 Free;
end;

Возможность ошибки убиваем на корню


 
_Юрий   (2010-09-30 19:53) [12]


> Anatoly Podgoretsky ©   (30.09.10 19:39) [11]


дык в данном случае неважно, локальная или нет.
И если отсутствует, все равно лишнее действие, проверка лишняя.
Либо конструктор вернет живой указатель, либо мы не попадем в секцию finally.
(Извращенные варианты типа перекрытия NewInstance и возврата nil рассматривать не будем :-))
Впрочем, не очень страшно.


 
Anatoly Podgoretsky ©   (2010-09-30 20:20) [13]

Узнаешь важно или нет, когда переменная будет изменена, например другим потоком, косвенно из какой либо функци или прямо в теле.

Насчет лишняя, так ты ведешь себя неспортивно, подсмотрел конкретную реализацию, а работа не должна зависить от внутренней реализации.


 
0x00FF00 ©   (2010-09-30 20:23) [14]


> Anatoly Podgoretsky ©   (30.09.10 19:35) [10]

И впрямь.
FreeAndNIL — исключительно для объектов, а не данных.
Эко меня умотало сегодня.
Приношу извинения за дезинформацию.


 
Anatoly Podgoretsky ©   (2010-09-30 20:33) [15]

> 0x00FF00  (30.09.2010 20:23:14)  [14]

Еще хуже, тип объявлен как нетипизированый указатель!


procedure FreeAndNil(var Obj);


То есть ты формально прав, подавая туда указатель. И поскольку Борланд убила
типизацию, то никакой ошибки при компиляции не возникнет.


 
faiwer ©   (2010-09-30 21:07) [16]


> Для этого не надо использовать эту уродскую процедуру, а
> надо написать свою FreeEx(var A: TObject)


procedure FreeAndNil(var Obj);
var
 Temp: TObject;
begin
 Temp := TObject(Obj);
 Pointer(Obj) := nil;
 Temp.Free;
end;


Чем стандартный вариант (^) плох? Я о5 что-то недопонял?)


 
faiwer ©   (2010-09-30 21:09) [17]

Под FreeEx(var A: TObject) подразумевается это?

procedure FreeEx(var A: TObject)
var
 temp: TObject;
begin
 Temp:=A;
 A:=nil;
 Temp.Free;
end;


 
_Юрий   (2010-09-30 23:40) [18]


> Anatoly Podgoretsky ©   (30.09.10 20:20) [13]


> Узнаешь важно или нет, когда переменная будет изменена,
> например другим потоком, косвенно из какой либо функци или
> прямо в теле.


Если так, то это вообще ошибочный код - с трай-файналли

> а работа не должна зависить от внутренней реализации.


А это документированная фича, внутренняя реализация ни при чем :-)


> а надо написать свою FreeEx(var A: TObject)


Так не получится потому, что нельзя будет подставлять потомков от TObject (то есть ничего вообще), компилятор требует строгого соответствия типов для var параметров. Поэтому борланд и забили тут на типизацию


 
_Юрий   (2010-09-30 23:44) [19]


> faiwer ©   (30.09.10 21:07) [16]
>
>



> Чем стандартный вариант (^) плох? Я о5 что-то недопонял?
> )
>


Он потенциально приводит к ошибкам, потому что тут нет типизации.
Пример:
Был у меня экземпляр класса, создавался в одном месте и разрушался в другом (с помощью FreeAndNil)
а потом я решил ослабить связи, и заменил его на интерфейс.
А разрушение убрать забыл.  Компилятор все пропускает, а в ран-тайм имеем нарушение по памяти. И хорошо еще, если сразу вылезет.



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

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

Наверх




Память: 0.51 MB
Время: 0.009 c
15-1284321619
DVM
2010-09-13 00:00
2010.12.26
С Днем Программиста!!!


2-1283250786
madmech
2010-08-31 14:33
2010.12.26
Проблема с рисованием на канве TDBGrid


2-1285944015
Первокурсница
2010-10-01 18:40
2010.12.26
Экспортировать отчёт из Delphi в MsWord,дублировать запрос в Lbl


15-1284562752
Unknown_user
2010-09-15 18:59
2010.12.26
Написание собственного COM сервера автоматизации


2-1286186824
Overclocker
2010-10-04 14:07
2010.12.26
Работа с файлами