Текущий архив: 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.48 MB
Время: 0.005 c