Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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;
и не париться.





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

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

Наверх





Память: 0.48 MB
Время: 0.009 c
1-57754
voland0
2002-04-05 12:37
2002.04.18
Помогите!!! onStartDrag в TDBGrid не наступает!!!


3-57628
skiph
2002-03-28 12:33
2002.04.18
Логическое поле в таблице


1-57804
ZPS
2002-04-06 00:38
2002.04.18
PopupMenu1 - поменять цвет ?


3-57661
KVT2000
2002-03-29 08:53
2002.04.18
DBGrid, последовательность событий


3-57653
Sergey_R
2002-03-26 18:19
2002.04.18
Ничего не понимаю...В SQLExplorer работает, напрямую из...





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