Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.18;
Скачать: [xml.tar.bz2];




Вниз

Когда правильно делать 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;
и не париться.





Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.18;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.028 c
1-57744           andr                  2002-04-05 13:13  2002.04.18  
Как посчитать кол-во дней между 2 датами?


3-57587           Malder                2002-03-26 18:51  2002.04.18  
НЕсовместимость D4 и D5


1-57723           maxnovikov            2002-04-08 11:45  2002.04.18  
data types and reserved words


7-57899           Nikolay               2002-01-24 08:37  2002.04.18  
DRV


3-57596           anod                  2002-03-26 22:31  2002.04.18  
2 Простых вопроса