Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1285973896
Ghost del vonte
2010-10-02 02:58
2010.12.26
Графика


15-1284321619
DVM
2010-09-13 00:00
2010.12.26
С Днем Программиста!!!


15-1284617463
boriskb
2010-09-16 10:11
2010.12.26
Завершился конкурс


15-1284537412
12
2010-09-15 11:56
2010.12.26
MSSQL. OPENQUERY. Как linked_server := self ?


2-1274640351
vegarulez
2010-05-23 22:45
2010.12.26
Докачка файлов через idhttp.





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