Форум: "Начинающим";
Текущий архив: 2010.12.26;
Скачать: [xml.tar.bz2];
ВнизУничтожение объекта Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.005 c