Форум: "Прочее";
Текущий архив: 2009.12.27;
Скачать: [xml.tar.bz2];
ВнизСтатья на хабаре про Делфи «создание и уничтожение объектов...» Найти похожие ветки
← →
Kolan © (2009-10-22 22:38) [0]Читали?
http://habrahabr.ru/blogs/delphi/72959/
Особенно запомнилось: «Соответственно, в деструкторе достаточно корректно обрабатывать нулевые значения, в чем сильно помогает процедура FreeAndNil, которая освобождает объект, только если ссылка на него уже не nil.»
А Free что делает интересно?
← →
Игорь Шевченко © (2009-10-22 22:45) [1]Нормальная статья. Ошибся человек, с FreeAndNil - бывает. Лучше бы задать вопрос ему, а не здесь, но это уже издержки воспитания.
← →
GDI+ (2009-10-22 22:54) [2]
> Kolan © (22.10.09 22:38)
Вызови Free любого объекта дважды и поймаешь Exception.
А FreeAndNil корректно обрабатывает эту ситуацию приближая простоту программирования на Delphi к C# и Java.
На том же C++ я в деструкторах обычно пишу
if (NULL != obj){
delete obj;
obj = NULL;
}
кода чуть больше но мне потом спокойнее.
← →
Игорь Шевченко © (2009-10-22 23:04) [3]
> Вызови Free любого объекта дважды и поймаешь Exception.
а нафига вызывать дважды ?
← →
test © (2009-10-22 23:09) [4]Посмотри что ли в source Free еще и FreeAndNil может мысли будут.
← →
@!!ex © (2009-10-22 23:11) [5]> [2] GDI+ (22.10.09 22:54)
Ну да!
Замаскировать ошибку в архитектуре(а множественное удаление объекта ничем другим не является), вместо того, чтобы корректно его обработать - это конечно замечательное решение.
← →
jack128_ (2009-10-22 23:29) [6]
> Ошибся человек, с FreeAndNil - бывает.
он осознано написал FreeAndNil.
Мы как раз сегодня на работе холиварили на эту тему. Единственный вменяемый довод против FreeAndNil"a был, то что у него параметр - не типизированный.
← →
Игорь Шевченко © (2009-10-22 23:33) [7]
> Мы как раз сегодня на работе холиварили на эту тему
ну раз вы, тогда конечно...
← →
Hint (2009-10-22 23:33) [8]Читал и даже код FreeAndNil скопировал, т.к. перепутаны причина и следствие (FreeAndNil устанавливает объект в nil после чего уже не выполняется условии в методе Free, а не наоборот).
← →
test © (2009-10-22 23:37) [9]Hint (22.10.09 23:33) [8]
в начале, ты ничего не контролируешь
← →
@!!ex © (2009-10-22 23:46) [10]> [6] jack128_ (22.10.09 23:29)
Не смогу придумать ни одного довода в пользу использования FreeAndNil.
Разве что кто-то делает проверку типа: if Assigned(Object) then
Но
1) Это довольно редко нужно. Ради этого городить кучу лишних никому не нужных вызовов зачем?
2) В таких сулчаях можно и самому проследить за обнулением переменной.
← →
jack128_ (2009-10-22 23:52) [11]
>
> Не смогу придумать ни одного довода в пользу использования
> Free.
> Разве что кто-то делает проверку типа: if Assigned(Object)
> then
> Но
> 1) Это довольно редко нужно. Ради этого городить кучу лишних
> никому не нужных вызовов зачем?
> 2) В таких сулчаях можно и самому проследить за обнулением
> переменной.
зы там на харбе ссылка проскочила: http://gunsmoker.blogspot.com/2009/04/freeandnil-free.html
← →
Игорь Шевченко © (2009-10-22 23:55) [12]jack128_ (22.10.09 23:52) [11]
Ее уже здесь обсуждали, выяснили, что неполезная
← →
oxffff © (2009-10-22 23:57) [13]Все выкрутасы с Freeandnil связаны c избежанием циклических ссылок.
И порядок внутри нее корректен. В остальном он ... не нужен.
Вот упрощенный пример применения freeandnil.
Aobject=class
Link:Tobject;
destructor destroy;override;
end;
procedure TForm4.FormCreate(Sender: TObject);
var a,b:Aobject;
begin
a:=Aobject.Create;
b:=Aobject.Create;
a.Link:=b;
b.Link:=a;
freeandNil(a.Link);
end;
{ Aobject }
destructor Aobject.destroy;
var abcs:Tobject;
begin
link.Free;
showmessage("removed");
inherited;
end;
← →
jack128_ (2009-10-22 23:58) [14]
>
> Ее уже здесь обсуждали, выяснили, что неполезная
нда. Жаль, видимо пропустил это обсуждение.
← →
Игорь Шевченко © (2009-10-22 23:59) [15]jack128_ (22.10.09 23:58) [14]
Когда в заголовке написано - "Почему всегда следует использовать FreeAndNil вместо Free", дальше можно не читать
← →
jack128_ (2009-10-23 00:02) [16]
> В остальном он ... не нужен.
он позволяет выявлять ошибки, когда объект используется после его освобождения (в рамках одной процедуры). Мы получает гарантированный AV, в отличии от простого Free.
а это даже не важно, что в остальном он нужен или же нет. важно то, что _иногда_ он приносит пользу, а вот вреда он не приносит. так что баланс за FreeAndNil
← →
Kolan © (2009-10-23 00:03) [17]oxffff, похоже на плохой дизайн. Зачем объект в своем деструкторе удаляет то, что не сам создал?
← →
oxffff © (2009-10-23 00:05) [18]
> Мы получает гарантированный AV
Это неправда. Гарантированного AV неполучишь.
> а вот вреда он не приносит.
Как не приносит. Дополнительный вызов - лишние наклданые расходы.
← →
Игорь Шевченко © (2009-10-23 00:07) [19]
> он позволяет выявлять ошибки, когда объект используется
> после его освобождения (в рамках одной процедуры).
Это ошибка архитектуры, это не лечится.
← →
oxffff © (2009-10-23 00:11) [20]
> Kolan © (23.10.09 00:03) [17]
Этот пример надуман. Здесь основная идея в том, что декструктор может вызывать другие функции,которые вызовут освобождения других объектов, которые могут вызвать цикл освобождений.
Чтоб его распутать используют freeandnil.
Что касаемо дизайна. Я не могу сказать его ли это последствия или нет.
такие ситуации бывают. Это подход к их решению.
← →
jack128_ (2009-10-23 00:12) [21]
>
> Это неправда. Гарантированного AV неполучишь.
хм. ну хорошо, я не получу гарантрровонного фМ в случае, если вызываемый метод объекта не обращается к его(обхекта) поляим и не вызывает его виртуальных методов. Но согласись - таких методов практически не бывает. а если они таки есть - то лудше их сделать классовыми.
← →
@!!ex © (2009-10-23 00:13) [22]> [16] jack128_ (23.10.09 00:02)
Как надо говнокодить, чтобы обращаться к удаленному объекту??
Я просто даже ситуации не могу представить не идиотскую ситуацию в которой может возникнуть такая проблема.
← →
Игорь Шевченко © (2009-10-23 00:14) [23]jack128_ (23.10.09 00:12) [21]
Если ты борешься за чистоту объектов, почему не борешься на неиспользование после уничтожения ?
← →
oxffff © (2009-10-23 00:16) [24]
> если вызываемый метод объекта не обращается к его(обхекта)
> поляим
Он даже может к полям обращаться и AV не будет в одних случаях, при их наличии в других. Это как говориться где объект в куче ляжет.
С виртуальными согласен.
← →
jack128_ (2009-10-23 00:22) [25]
>
> Как надо говнокодить, чтобы обращаться к удаленному объекту?
> ?
> Я просто даже ситуации не могу представить не идиотскую
> ситуацию в которой может возникнуть такая проблема.
о - я правильно понимаю, что у тебя никогда не бывает AV"шек ?? ну могу сказать, что ты крут, как три яйца в крутую =). А вот например дельфя их периодически выдает. Причем AV не по нулевому адресу.
> Он даже может к полям обращаться и AV не будет в одних случаях,
> при их наличии в других.
obj := TObj.Create;
FreeAndNil(obj);
Caption := obj.StrField; // при каких условиях здесь не возникнет AV ??
> Если ты борешься за чистоту объектов, почему не борешься
> на неиспользование после уничтожения ?
борюсь. Именно для борьбы с использованием объекта после его разрушения и использую FreeAndNil.
← →
Игорь Шевченко © (2009-10-23 00:31) [26]jack128_ (23.10.09 00:22) [25]
Это не борьба, это приучение к костылям. Ногами ходить гораздо удобнее, поверь.
Кстати, у меня не бывает AV. Удивись.
← →
oxffff © (2009-10-23 00:36) [27]
> Игорь Шевченко © (23.10.09 00:31) [26]
Приветствую.
Я бы не очень бы спешил с выводами что это плохой дизайн. Можно привести пример. Есть пул объектов. Они все должны освободиться как только будет принудительно освобожден любой первый из них.
← →
oxffff © (2009-10-23 00:40) [28]
> obj := TObj.Create;
> FreeAndNil(obj);
> Caption := obj.StrField; // при каких условиях здесь не
> возникнет AV ??
Все зависит где будет объект в кучи. AV возникает как исключение процессора например на отсутствие проекции линейного адреса на физической в каталоге страниц.
← →
GDI+ (2009-10-23 00:40) [29]
> @!!ex © (22.10.09 23:11) [5]
>
> > [2] GDI+ (22.10.09 22:54)
>
> Ну да!
> Замаскировать ошибку в архитектуре(а множественное удаление
> объекта ничем другим не является), вместо того, чтобы корректно
> его обработать - это конечно замечательное решение.
Тогда Java и C# это одна глобальная ошибка, так как там программист о таких мелочах, как о памяти вообще не беспокоится.
← →
@!!ex © (2009-10-23 00:56) [30]> [25] jack128_ (23.10.09 00:22)
> о - я правильно понимаю, что у тебя никогда не бывает AV"шек
> ?? ну могу сказать, что ты крут, как три яйца в крутую =)
> . А вот например дельфя их периодически выдает. Причем AV
> не по нулевому адресу.
Бывает. Но я не могу припомнить случая, чтобы эти AV были вызваны удаленным объектом, к которому идет обращение.
P.S. Сейчас 90% AV из-за обращения по нулевому адресу. :)
> [29] GDI+ (23.10.09 00:40)
Не путайте кислое с длинным. Там архитектура с GC, это не тоже самое что архитектура в которой допустимо множественное удаление(Вы сможете придумать пример не индусского кода, в котором два раза объект пытаются удалить?).
← →
Kolan © (2009-10-23 00:59) [31]
> Есть пул объектов. Они все должны освободиться как только
> будет принудительно освобожден любой первый из них.
Тот кто убивает один из объектов, пусть убьёт и остальные. И вообще это, если я правильно понимаю, по смыслу равняетсяTObjectList.Clear();
.
← →
Германн © (2009-10-23 01:21) [32]
> Игорь Шевченко © (23.10.09 00:31) [26]
>
> jack128_ (23.10.09 00:22) [25]
>
> Это не борьба, это приучение к костылям. Ногами ходить гораздо
> удобнее, поверь.
>
> Кстати, у меня не бывает AV. Удивись.
>
С костылями согласен, тем более что этих костылей в эпоху моей максимальной Дельфи-активности и не было. Но AV бывает регулярно. При завершении работы приложения.
← →
Игорь Шевченко © (2009-10-23 01:45) [33]oxffff © (23.10.09 00:36) [27]
Вечер добрый!
> Я бы не очень бы спешил с выводами что это плохой дизайн.
> Можно привести пример. Есть пул объектов. Они все должны
> освободиться как только будет принудительно освобожден любой
> первый из них.
Как ты понимаешь, всякий механизм имеет право на применение в наиболее подходящих случаях. Можно составить конструкцию, когда необходимо будет применять FreeAndNil (собственно, в VCL и таких примеров есть), но применять FreeAndNil для диагностики огрехов кривой архитектуры - это, боюсь, крайне неуместное применение.
Собственно для диагностики применяются юнит-тесты и просто тесты, они огрехи выявят гораздо эффективнее.
← →
Игорь Шевченко © (2009-10-23 01:48) [34]Германн © (23.10.09 01:21) [32]
> Но AV бывает регулярно. При завершении работы приложения.
У меня и при завершении не бывает :(
← →
Германн © (2009-10-23 01:55) [35]
> <Цитата>
>
> Игорь Шевченко © (23.10.09 01:48) [34]
>
> Германн © (23.10.09 01:21) [32]
>
>
> > Но AV бывает регулярно. При завершении работы приложения.
>
>
>
> У меня и при завершении не бывает :(
>
Нууу. С одной стороны ты, имхо, не используешь, а с другой тоже не используешь.
Это я про сторонние компоненты.
← →
Игорь Шевченко © (2009-10-23 02:00) [36]Германн © (23.10.09 01:55) [35]
Использую :) Сторонние компоненты - они же тоже пишутся не в расчете на то, что при их использовании AV будет необходимым следствием.
← →
Германн © (2009-10-23 02:20) [37]
> Игорь Шевченко © (23.10.09 02:00) [36]
>
> Германн © (23.10.09 01:55) [35]
>
> Использую :)
Не знал. Теперь знаю.
Значит имело значение нечто другое.
← →
GDI+ (2009-10-23 04:40) [38]
> @!!ex © (23.10.09 00:56) [30]
> > [29] GDI+ (23.10.09 00:40)
>
> Не путайте кислое с длинным. Там архитектура с GC, это не
> тоже самое что архитектура в которой допустимо множественное
> удаление(Вы сможете придумать пример не индусского кода,
> в котором два раза объект пытаются удалить?).
Чаще это бывает когда требования к архитектуре и функционалу со стороны заказчика меняются на-лету, объекты с циклическими ссылками друг на друга и вся совокупность требований сложноформализуема.
Если архитектуру решения можно без проблем легко описать в документации, то FreeAndNil не нужно. Но так как требования могут поменяться несколько раз в процессе разработки то оно очень нужно. Это лучше чем AV на продакшене, даже если в этом AV виновато чужое кривое планирование.
← →
oxffff © (2009-10-23 07:39) [39]
> Kolan © (23.10.09 00:59) [31]
>
> > Есть пул объектов. Они все должны освободиться как только
>
> > будет принудительно освобожден любой первый из них.
>
> Тот кто убивает один из объектов, пусть убьёт и остальные.
> И вообще это, если я правильно понимаю, по смыслу равняется
> TObjectList.Clear();.
Потребитель может не знать о существовании других объектов и о пуле в частности. Они например могут использоваться другимим потребителями.
← →
jack128_ (2009-10-23 09:56) [40]
> Кстати, у меня не бывает AV. Удивись.
А. Ну тогда конечно.
Кста, а зачем тут: http://delphimaster.net/view/3-1239773025/ в восьмом посте ты вызвал: DBParams.Free; а не DBParams.Destroy ?
> Все зависит где будет объект в кучи.
"объект в куче" расположен по адресу nil, потому что я строчкой выше вызвал FreeAndNil.
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2009.12.27;
Скачать: [xml.tar.bz2];
Память: 0.63 MB
Время: 0.008 c