![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Освобождение ресурса в finally
Arinyshka © (2008-04-23 12:17:00)
Страницы: < 1 2 ... 24 25 26 27 28 29 30 31 32 33 >
Не подскажете еще один момент:
Есть процедура, выглядит примерно так
procedure TSetPayFrm.BtnAddImageClick(Sender: TObject);
var TempBitmap:TBitmap;
begin
if not(opendialog1.Execute) then exit;
try
TempBitmap := TBitmap.Create;
TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
TempBitmap.Free;
end;
end;
На освобождение TempBitmap.Free; выдает варнинг
[Warning] uSetPaymentMain.pas(313): Variable 'TempBitmap' might not have been initialized
Не смертельно, но непонятно... почему варнинг? При изменениии условия и включении всей конструкции в один блок begin..end ситуация не менялась.
Palladin (2008-04-24 14:26:00) [561]
> Объектов 5-6 наберется.
каких например?
ANB (2008-04-24 14:24:00) [562]Простенький пример :
имеем хитрый текстовый файл, который надо разобрать на клиенте, закачать в БД и потом обработать уже хранимкой.
В процессе разбора иногда придется опять таки обращаться к БД за уточнением информации.
Ошибочные строки надо записать в другой файл и при этом еще вести лог обработки.
Объектов 5-6 наберется.
Естественным подходом в таком случае будет создать все объекты заранее и только по окончании процедуры удалить.
Городить вложенные 5-6 трай - файнелли - жуткий изврат. Весь код фактически вправо уйдет.
Плюс в файнелли возможно придется запихать и некоторые действия, отличающиеся от уничтожения объекта.
Это что получится - на кажную строчку в файнелли надо отдельный блок заводить ? А если потом выяснилось, что объект не нужен был - обратно все убирать ?
ИМХО - в функции должен быть один блок трай - файнелли.
Palladin (2008-04-24 14:21:00) [563]
> ANB (24.04.08 14:13) [89]
кто не писал? я неписал?
ANB (2008-04-24 14:13:00) [564]
> Palladin © (24.04.08 13:57) [86]
> Обниление идентификаторов и перенос конструктора в try выглядит
> как-то неестественно, но это так, придирка не посуществу.
> Другое беспокоит, не знаю как кто, но у меня обычно в локальных
> перменных не числится больше трех-четырех объектов, а если
> и числится, то используются они в разных временных рамках
> и на каждый идет блок try finally, если же происходит раздувание
> количества, то это первая ласточка к разделению процедуры/метода
> на несколько шагов и оформлении их в виде отдельных процедур/методов.
> Разделяй и влавствуй, как говорится. Так что, обниление
> идентификаторов, это совет тем кто не умеет структурировать
> программу и лепит все в один.
Значится не писал достаточно сложных программ. :)
Восхищенный (2008-04-24 14:11:00) [565]> Palladin © (24.04.08 13:57) [86]
В самую точку.
ANB (2008-04-24 14:10:00) [566]
> ЮЮ © (24.04.08 12:36) [76]
> > [74] ANB (24.04.08 12:30)
>
> > Вобчем то да. Но могут быть разные глюки потом
>
>
> Глюки после смерти? Если они есть, значит проблемы в другом
> месте кода и это счастье, что тебе удалось уловить их хотя
> бы опосредованно.
Да я не нарывался ни разу.
Palladin (2008-04-24 13:57:00) [567]Обниление идентификаторов и перенос конструктора в try выглядит как-то неестественно, но это так, придирка не посуществу. Другое беспокоит, не знаю как кто, но у меня обычно в локальных перменных не числится больше трех-четырех объектов, а если и числится, то используются они в разных временных рамках и на каждый идет блок try finally, если же происходит раздувание количества, то это первая ласточка к разделению процедуры/метода на несколько шагов и оформлении их в виде отдельных процедур/методов. Разделяй и влавствуй, как говорится. Так что, обниление идентификаторов, это совет тем кто не умеет структурировать программу и лепит все в один.
Jack128_ (2008-04-24 13:43:00) [568]
> начит проблемы в другом месте кода и это счастье, что тебе
> удалось уловить их хотя бы опосредованно.
не фига. как раз если не обниливать переменную после уничтожения - то проблема может и не проявиться(точнее проявиться - но у юзера), а вот если юзать FreeAndNil - то ошибка ГАРАНТИРОВАННО проявиться.
var
O: TObject;
begin
O := TObject.Create;
try
Caption := O.ClassType.ClassName;
finally
O.Free;
end;
Caption := O.ClassType.ClassName; // ошибочный код. Но AV не будет.
end;
Поэтому я почти всегда юзаю FreeAndNil
Восхищенный (2008-04-24 13:20:00) [569]> {RASkov} © (24.04.08 13:01) [83]
Поставь на первой строке конструктора бряк и посмотри, что будет в окне CPU передэтим бряком. Там увидишь вызов функции из System (не помню точное название, что-то типа _CreateInstance), которая реально выделяет память и создает объект (ее код можно посмтреть). А на первой строке конструктора объект уже создан и даже проинициализирован (InitInstance), и сам конструктор, по сути, всего лишь дает возможность его дополнительной (юзерской) инициализации. Ну и есть там еще блок try-except (тоже вставленный компилятором) - это уже к сабжу относится (разрушение объекта при исключении в конструкторе).
{RASkov} (2008-04-24 13:01:00) [570]> [82] Восхищенный (24.04.08 12:57)
> Ты, возможно, удивишься
Нет, не удевлюсь, так как то что мы видим в редакторе кода для компилятора это совсем другое :)
А честно - "не знал"... Т.е. именно такое про конструктор слышу в первый раз.
Восхищенный (2008-04-24 12:57:00) [571]> {RASkov} © (24.04.08 12:50) [80]
> Его нужно применять к классу, иначе(если к объекту: Obj.Create;) это не
> конструктор а вызов метода Create без распределения памяти....
Ты, возможно, удивишься, но метод Create не выделяет память даже если он был вызван и через ссылку на класс. Память выделяется другим кодом, который в этом случае автоматически вставляется компилятором перед непосредственным вызовом Create. Это просто compiler-magic фича такая и к классовым методам она никакого отношения не имеет.
{RASkov} (2008-04-24 12:50:00) [572]> [79] Kolan © (24.04.08 12:46)
> так что, имхо, классовый.
Коструктор, да. Его нужно применять к классу, иначе(если к объекту: Obj.Create;) это не конструктор а вызов метода Create без распределения памяти....
Но я зря его(конструктор) подчеркнул, так как разговор был о Free)
Восхищенный (2008-04-24 12:50:00) [573]> Kolan © (24.04.08 12:46) [79]
Проверь, что такое Self внутри конструктора - и имхо твое изменится, и имхом быть перестанет.
Kolan (2008-04-24 12:46:00) [574]> но не классовый он
Имхо, словоconstructorподразумеваетclass function, так что, имхо, классовый.
{RASkov} (2008-04-24 12:42:00) [575]> [70] ZENsan © (24.04.08 12:23)
TObject = class
constructor Create;
procedure Free;
classfunction InitInstance(Instance: Pointer): TObject;
procedure CleanupInstance;
function ClassType: TClass;
classfunction ClassName: ShortString;
classfunction ClassNameIs(const Name: string): Boolean;
......
Я конечно загнул с приватным :) но не классовый он....
Восхищенный (2008-04-24 12:40:00) [576]> ZENsan © (24.04.08 12:26) [72]
> Constructor i Destructor - единственные класс методы до реализации класс
> методов в делфи начиная по моему с 2005-ого..
1. Конструктор и деструктор - вообще не классовые методы.
2. Классовые методы реализованы во всех версиях Delphi, начиная аж с 1.
3. В [65] Плохиш дал очень хороший совет. Конечно, можно и дальше переливать здесь из пустого в порожнее, но лучше все же последовать этому совету.
ЮЮ (2008-04-24 12:36:00) [577]> [74] ANB (24.04.08 12:30)
> Вобчем то да. Но могут быть разные глюки потом
Глюки после смерти? Если они есть, значит проблемы в другом месте кода и это счастье, что тебе удалось уловить их хотя бы опосредованно.
ЮЮ (2008-04-24 12:32:00) [578]> Я именно про случай если это локальные переменные не константы
зачем тогда
finally
FreeAndNil(Obj1);
FreeAndNil(Obj2);
end;
так разве менее красиво
finally
Obj1.Free;
Obj2.Free;
end;
P.S. учитывая, что Obj2 := TObj2.Create; часто вызывает исключение, очень вероятно, что при удачном создании обоих объектов упадет с исключением Obj1.Free; и Obj2 останется неосвобожденным :)
ANB (2008-04-24 12:30:00) [579]
> то нет смфсла в их обNilениее в finally
Вобчем то да. Но могут быть разные глюки потом. Ну его нафиг - мне что жалко один раз выполнить короткое присваивание ? Тем более оно в функции живет.
ZENsan (2008-04-24 12:27:00) [580]Если поля обйекта то конечно. Я именно про случай если это локальные переменные не константы..