Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
3-1231878365
serko
2009-01-13 23:26
2009.12.27
Вместо русских букв вопросительные знаки...


15-1256758600
DillerXX
2009-10-28 22:36
2009.12.27
Бинокль


15-1256309335
YurikGL
2009-10-23 18:48
2009.12.27
Тупо списали с видеокамеры, теперь оно не играет


1-1231565298
2009Man
2009-01-10 08:28
2009.12.27
как определить компонент на который перетащили файлы


15-1256703324
Омлет
2009-10-28 07:15
2009.12.27
Занимательное программирование :)





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