![]() |
| ||
|
|
Новости |
Поиск |
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 ситуация не менялась.
Anatoly Podgoretsky (2008-04-23 16:32:00) [621]> Arinyshka (23.04.2008 15:09:24) [24]
> Проблема в том, что он мне нужен и в других юнитах, на протяжении работы приложения
В таком случае никаких переменных, переместить в класс, а доступ через контролируемое свойство Gettet/Setter и даже создавать извне не надо, Gettet/Setter с этим сами справятся. Никаких проблем с достоверность указателя не будет, всегда истинное.
ANB (2008-04-23 16:31:00) [622]
> Palladin © (23.04.08 13:53) [23]
> Автор Александр Просторов, всемирно известный классик кодирования.
> всем пасть ниц
>
> Тема многократного использования идентификатора объекта
> не раскрыта
На SQL.ru сходи - познакомся.
Andy BitOff (2008-04-23 16:09:00) [623]В Init в except FreeAndNil(ListImage), а ListImage:=TStringList.Create вынести над try. Далее по коду, если надо обратиться к ListImage делаешь проверку не Nil ли он.
Arinyshka (2008-04-23 15:50:00) [624]ой, имела в виду список свой.
Arinyshka (2008-04-23 15:48:00) [625]
> ListImage:=TStringList.Create; идет на верх над try
> в finally пишем FreeAndNil(ListImage) ну или
> ListImage.Free;
> ListImage:=Nil;
Подождите... разве я не потеряю значения nil? Я инициализировала и освободила?
Восхищенный (2008-04-23 15:26:00) [626]Какая интересная дискуссия. И что интересно - ни одного повтора.
Palladin (2008-04-23 15:18:00) [627]ListImage:=TStringList.Create; идет на верх над try
в finally пишем FreeAndNil(ListImage) ну или
ListImage.Free;
ListImage:=Nil;
в объявлении Var пишем
ListImage:TStringList=Nil;
Рамиль (2008-04-23 15:15:00) [628]Не надо загонять в try создание объекта. Если возникла ошибка при его создании, то вызывать деструктор лишено какого либо смысла.
Arinyshka (2008-04-23 15:09:00) [629]Уффф... ну и дискуссия :)
А вот я еще один объект завожу... освобождаю по form.Close.
unit u;
interface
type
TSetPayFrm = class(TMGSprForm)
var
SetPayFrm : TSetPayFrm;
ListImage:TStringList;
implementation
procedure TSetPayFrm.InitImageList;
var MyStream: TStream; TempBitmap:TBitmap;
begin
try
ListImage:=TStringList.Create;
except
ListImage.Free;
end;
procedure TSetPayFrm.TbCloseClick(Sender: TObject);
begin
Close;
end;
procedure TSetPayFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ListImage.Free;
Action := caFree;
end;
end.
Проблема в том, что он мне нужен и в других юнитах, на протяжении работы приложения. Поэтому в процедурке, создающей его, finaly меня не устраивает.
Но в случае except у меня 2 освобождения... Где я неправа?
Palladin (2008-04-23 13:53:00) [630]Автор Александр Просторов, всемирно известный классик кодирования. всем пасть ниц
Тема многократного использования идентификатора объекта не раскрыта
ANB (2008-04-23 13:40:00) [631]http://softwarer.ru/memory.html
Читать сомневающимся до полного просветления.
Пользуюсь этим способом практически везде, даже если нужен только один объект, т.к. заранее не знаешь, обойдешься одним или нет. И ни разу не ловил из-за этого АВ.
{RASkov} (2008-04-23 13:20:00) [632]> [20] Плохиш © (23.04.08 13:19)
> При возникновении исключения в конструкторе, операция присваивания
> не будет выполнена.
:)
Ну да... тоже верно... Но все равно [1] мне кажется вернее...
Плохиш (2008-04-23 13:19:00) [633]
> А если после возникновения ошибки в конструкторе, он(конструктор)
> вернет не рыбу не мясо... т.е. не nil и не объект...
При возникновении исключения в конструкторе, операция присваивания не будет выполнена.
{RASkov} (2008-04-23 13:15:00) [634]> [16] ANB (23.04.08 12:44)
> TempBitmap := nil;
> try
> TempBitmap := TBitmap.Create;
> TempBitmap.LoadFromFile(OpenDialog1.FileName);
> finally
> TempBitmap.Free;
> end;
>
> Это классика.
А по мне, мне кажется [1] более роднее и вернее.... [16] и выглядит как-то подозрительно...
А если после возникновения ошибки в конструкторе, он(конструктор) вернет не рыбу не мясо... т.е. не nil и не объект...
Я правда трудно себе это представляю, но.... в финале АВ :)
Leonid Troyanovsky (2008-04-23 13:12:00) [635]
> ANB (23.04.08 12:44) [16]
> Это классика.
Это заблуждение.
Исключения конструктора следует передавать обработчику
следующего уровня.
А защищать ресурсы в этом случае не нужно - деструктор
вызовется автоматом.
--
Regards, LVT.
{RASkov} (2008-04-23 12:47:00) [636]> [9] Ega23 © (23.04.08 12:30)
> Button2Click
В этом случае мы попадаем в финал так как коструктор тоже в защитном блоке...
ANB (2008-04-23 12:44:00) [637]
> TempBitmap := TBitmap.Create;
> try
> TempBitmap.LoadFromFile(OpenDialog1.FileName);
> finally
> TempBitmap.Free;
> end;
TempBitmap := nil;
try
TempBitmap := TBitmap.Create;
TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
TempBitmap.Free;
end;
Это классика. Позволяет избежать дублирования финалли, если объектов много, при этом все корректно отработает.
{RASkov} (2008-04-23 12:42:00) [638]> [9] Ega23 © (23.04.08 12:30)
А вот такой вариант:
function CrBut: TButton;
begin
Result:=TButton.Create(nil);
Result.Tag:=Random(15);
Result.Caption:=IntToStr(Result.Tag);
if Result.Tag<7 then begin
raise Exception.Create('Error in constructor');
Result.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var B: TButton;
begin
Randomize;
B:=CrBut;
try
B.Parent:=Self;
B.Caption:=B.Caption+' Ok';
ShowMessage('B Ok');
finally
B.Free;
ShowMessage('Finally');
end;
end;
Anatoly Podgoretsky (2008-04-23 12:38:00) [639]
> Потому что если в конструкторе произойдёт исключение, то
> TempBitmap будет равен nil.
Это ты погорячился, переменная то локальная, а субъект не является субъектом с регулируемым сроком жизни.
Anatoly Podgoretsky (2008-04-23 12:36:00) [640]> Arinyshka (23.04.2008 12:17:00) [0]
Правильно говорит, код из Вредных Заветов
Создание должно быть до try