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

Вниз

Когда правильно делать FreeAndNil, а когда просто Free?   Найти похожие ветки 

 
lipskiy ©   (2002-04-03 21:34) [0]

Сабж.


 
Юрий Зотов ©   (2002-04-03 21:41) [1]

FreeAndNil отличается от Free лишь тем, что при уничтожении объекта сразу же очищает ссылку на него. Поэтому правильно и то, и другое, а выбирать нужно в каждом случае то, что требуется.


 
lipskiy ©   (2002-04-03 22:04) [2]

Ну так а в чем разница, ну то есть понятно, в чем разница между двумя способами, но вот если все время использовать FreeAndNil и не задумываться о том, что нилить когда-то и не нужно, то это корректно будет?


 
Макс Черных ©   (2002-04-03 23:00) [3]

>то это корректно будет?
Вполне корректно.


 
cypher ©   (2002-04-03 23:54) [4]

>Макс Черных

А мож и пример приведешь, где это нужно ?


 
Chepel   (2002-04-04 00:19) [5]

Только не надо забывать, что FreeAndNil на самом деле делает NilAndFree. Те, если при уничтожении объекта возникнет екзепшин - то ссылки на объект уже нет... налицо потенциальный источник мемори ликов...

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


 
Макс Черных ©   (2002-04-04 01:04) [6]

>cypher
Да без проблем, вот две процедуры одного из моих
компонентов, что они делают, надеюсь, объяснять не надо.

destructor TCustomNSListView.Destroy;
begin
OnEdited := nil;
FreeAndNil(FDataLink);
inherited Destroy;
end;


Если мы напишем FDataLink.Free, то в нижеследующем
методе получим Access Violation в момент закрытия
приложения, так как FDataLink уже Free, но еще не nil

procedure TCustomNSListView.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and (AComponent = NSExplorer)
then NSExplorer := nil;
end;


 
MBo ©   (2002-04-04 07:52) [7]

>cypher
пару раз в неделю возникает вопрос - как не создать объект второй раз. При использовании FreeAndNil достаточно просто проверять Assigned или на nil.


 
Anatoly Podgoretsky ©   (2002-04-04 09:29) [8]

Не надо допускать ситуации в повторном использование, чаще всего это проблема проектирования, да последнии 7 лет ни разу не потребовалось обнулять указатель. Исключения могут быть компоненты.
Кроме того я бы рекомендовал не использовать FreeAndNil, так как теряется мощь Паскаля - строгая типизация, заменить парой
aVar.Free;
aVar := nil;


 
lipskiy ©   (2002-04-04 20:08) [9]

2 Anatoly Podgoretsky
Какие аргументы? Я не возражаю, что так м.б. правильнее, но почему именно? На что может повлиять нестрогая типизация при использовании FreeAndNil.

И вот еще, если использовать другой порядок, то нормально будет так:

procedure FreeAndNil(Obj:TObject);
begin
if Obj <> nil then
begin
Obj.Free;
Obj:= nil;
end;
end;


 
Anatoly Podgoretsky ©   (2002-04-04 20:35) [10]

А если Obj не TObject тогда как, вот это и значит нестрогая типизация, все сожрет.
Мне не тяжело написать в программе

Obj.Free;
Obj:= nil;

Хотя нужды ни разу не было, только объявление следующее
FreeAndNil(Obj:Pointer) а не TObject, если ты просто для примера взял это имя, для своей программы, то абсолютно лишнее Obj <> nil


 
Anatoly Podgoretsky ©   (2002-04-04 20:36) [11]

Ну и главное, ты уже понял что когда?


 
lipskiy ©   (2002-04-05 01:41) [12]

Когда нилить надо - понял.
А зачем разный порядок вызова free и nil - непонятно.
И почему Obj <> nil лишнее?
Если делать Free несуществующему объекту, ексепшена разве не будет?
А вообще, я всегда так и делал раньше:
Obj.Free;
Obj:= nil;
Причем последнюю строчку практически никогда и не требовалось писать, повоторное использование мне как-то не нужно было никогда.
Просто недавно заметил эту процедуру FreeAndNil, и возникли всякие глупые вопросы.


 
Anatoly Podgoretsky ©   (2002-04-05 07:54) [13]

"И почему Obj <> nil лишнее?"
Потому что это первое действие, которое делает Free

"Если делать Free несуществующему объекту, ексепшена разве не будет?"
Будет, а ты не делай, я серьезно.

Вот потому и возникла эта процедура, что практика повторного использования имеет быть.

Там сделано довольно умно, это защита от срабатывания разного рода событий, к сожалению иногда бывает наоборот, в основном где не проверяется на nil


 
lipskiy ©   (2002-04-05 16:51) [14]

Если первое что делает Free это Obj <> nil, то почему возникнет исключение, если объекта нет? Хм...
> Будет, а ты не делай
Да это понятно.
Только я склонен писать код так, чтобы написав кусок не держать его все время в голове, пусть он, этот кусок, сам разбирается со всеми возможными ситуациями, даже если они не будут происходить никогда. И когда я начну через некоторое время менять где-то что-то, то чтоб в других местах ошибок не вылезало.
А то напишешь проект, через полгода вернешься к нему для модификации - уже забыл все тонкости. Начнешь дергать в разных местах - и посыпались ошибки, так как где-то в коде-следствии не учтена ситуация, которую я сейчас спровоцировал в коде-причине.
Так лучше уж сразу обработать все вероятные варианты.
Я не прав в своем подходе?



 
reonid ©   (2002-04-05 17:02) [15]

>Если первое что делает Free это Obj <> nil, то почему возникнет >исключение, если объекта нет? Хм...

Пример
A := TList.Create;
B := A; // B ссылается на тот же объект, что и А
A.Free;
A := nil;
{или FreeAndNil(A);}
A.Free; // нет ошибки - А = nil
B.Free; // ошибка - B <> nil
{или FreeAndNil(B);}


 
Виктор Щербаков ©   (2002-04-05 17:15) [16]

Отсюда простой вывод: при уничтожении объекта надо обнулять все ссылки на него. Если их больше одной, то от FreeAndNil мало толку.


 
lipskiy ©   (2002-04-05 19:01) [17]

Окей, значит г-н Подгорецкий как всегда прав, надо делать везде руками
Obj.Free;
Obj:= nil;
и не париться.





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

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

Наверх




Память: 0.51 MB
Время: 0.014 c
1-57774
lipskiy
2002-04-03 00:35
2002.04.18
TThread: как вызвать его метод из основного потока и не ждать его


1-57731
Dan_
2002-04-08 13:49
2002.04.18
Проблема с TComboBox


1-57819
dr_neo_rostov
2002-04-05 14:24
2002.04.18
Двоичный вид числа и строки


4-57915
ctapik-net
2002-02-14 15:58
2002.04.18
Определениие списка компьютеров в сети.


1-57752
anod
2002-04-05 14:04
2002.04.18
drag n drop