Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.06.08;
Скачать: CL | DM;

Вниз

Освобождение ресурса в finally   Найти похожие ветки 

 
{RASkov} ©   (2008-04-24 10:59) [40]

> [36] ANB   (24.04.08 10:31)
> это написать и корректно и читабельно ?

Obj1  := TObj.Create;
 try
  Obj2  := TObj.Create;
  try
  Obj3  := TObj.Create;
   try
   Obj4  := TObj.Create;
    try
     Obj5  := TObj.Create;
     try
...
работа с объектами и куча другого кода
     finally
      FreeAndNil(Obj5);
     end;
    finally
     FreeAndNil(Obj4);
    end;
   finally
    FreeAndNil(Obj3);
   end;
  finally
   FreeAndNil(Obj2);
  end;
 finally
  FreeAndNil(Obj1);
 end;

или при уверенности, что в конструкторе не будет ошибок, то:
Obj1  := TObj.Create;
Obj2  := TObj.Create;
Obj3  := TObj.Create;
Obj4  := TObj.Create;
Obj5  := TObj.Create;
try
...
работа с объектами и куча другого кода
finally
FreeAndNil(Obj1);
FreeAndNil(Obj2);
FreeAndNil(Obj3);
FreeAndNil(Obj4);
FreeAndNil(Obj5);
end;
Но если честно, то у меня такого в коде никогда еще не встречалось :)


 
ZENsan ©   (2008-04-24 11:16) [41]

Удалено модератором


 
Arinyshka   (2008-04-24 11:28) [42]

А мне велено почитать про секцию  finalization. Может, так действительно проще?
инициализировать и освободить в соотв секциях...
Из советов мне понятен вариант с проверкой:
f Assigned(Obj1) then
  Obj1.Free;
i
тогда я никого не попытаюсь освободить дважды


 
ZENsan ©   (2008-04-24 11:31) [43]

Да делай именно так Аринишка - стандартный подход. Можно конечно и в секциях - так лучше если ты используеш этот код очень часто (не будешь каждый раз создавать и удалять объект..)


 
{RASkov} ©   (2008-04-24 11:33) [44]

> [42] Arinyshka   (24.04.08 11:28)
> f Assigned(Obj1) then
>  Obj1.Free;i
> тогда я никого не попытаюсь освободить дважды

Не факт. Смотри:
Obj1:=TObj.Create;
f Assigned(Obj1) then Obj1.Free;
f Assigned(Obj1) then Obj1.Free;

И тут АВ на второй строке.
Правильно так:
Obj1:=TObj.Create;
f Assigned(Obj1) then begin Obj1.Free; Obj1:=nil; end;
f Assigned(Obj1) then begin Obj1.Free; Obj1:=nil; end; //не будет АВ
ну или Freeandnil()...


 
ZENsan ©   (2008-04-24 11:34) [45]

Ну ето понятноъъъ Но мы же вроде про один блок Try Finally...

Там тогда просто надо:

If Assigned(Obj1) then
 FreaAndNil(Obj1);


 
{RASkov} ©   (2008-04-24 11:39) [46]

> [45] ZENsan ©   (24.04.08 11:34)

А смысл? не вижу...(
Но если еще и коструктор(ы) в защитный блок затащить, так еще и хинтов/варнингов от компилятора "слушать"...) Зачем?
И еще.... и даже с одним блоком финали мы не лишены возможности два раза освободить объект :)


 
ZENsan ©   (2008-04-24 11:43) [47]

Там обйектам нил присваивался перед блоком Трай.. Какие варнинги..
А если мы конструкторы в незащищённый блок поставим... то смотри:


Obj1 := TObj1.Create();{сработал, память выделилась}
Obj2 := TObj2.Create();{исключение}
try
 ...
finally
 ...
end;


Memory leak..


 
{RASkov} ©   (2008-04-24 11:48) [48]

> [47] ZENsan ©   (24.04.08 11:43)
> Там обйектам нил присваивался перед блоком Трай.. Какие варнинги..

Такой код появляется скорее из-за лени программиста нежели из-за профессианализма)
И для других может выглядеть запутанно :(


 
ANB   (2008-04-24 11:51) [49]


> Ega23 ©   (24.04.08 10:58) [39]
>
> > Затем, что ошибка может настичь и на Obj5  := TObj.Create;
>
> >  где же тогда освобождать Obj1 … Obj5
>
>
> А в таком случае надо по-хорошему так:
>
> Obj1 := TObj.Create;
> try
>  Obj2 := TObj.Create;
>  try
>    Obj3 := TObj.Create;
>    try
>       .......
>    finally
>      Obj3.Free;
>    end;
>  finally
>    Obj2.Free;
>  end;
> finally
>  Obj1.Free;
> end;
> <Цитата>

Извращение и плохо читаемо.


 
ZENsan ©   (2008-04-24 11:51) [50]

Не факт. Смотри:
Obj1:=TObj.Create;
if Assigned(Obj1) then Obj1.Free;
if Assigned(Obj1) then Obj1.Free;

Ну а такой код-то от чего появился вдруг?

if Assigned(Obj1) then Obj1.Free;
if Assigned(Obj1) then Obj1.Free;

Конечно тут ошибка будет


 
ZENsan ©   (2008-04-24 11:52) [51]

Полностйу соглаес с АНБ


 
ANB   (2008-04-24 11:52) [52]


>
> {RASkov} ©   (24.04.08 11:39) [46]
> > [45] ZENsan ©   (24.04.08 11:34)
>
> А смысл? не вижу...(
> Но если еще и коструктор(ы) в защитный блок затащить, так
> еще и хинтов/варнингов от компилятора "слушать"...) Зачем?
>
> И еще.... и даже с одним блоком финали мы не лишены возможности
> два раза освободить объект :)

Ни хинтов не варнингов при таком способе нету.


 
ANB   (2008-04-24 11:53) [53]


> Arinyshka   (24.04.08 11:28) [42]
> А мне велено почитать про секцию  finalization. Может, так
> действительно проще?
> инициализировать и освободить в соотв секциях...
> Из советов мне понятен вариант с проверкой:
> if Assigned(Obj1) then>   Obj1.Free;i
> тогда я никого не попытаюсь освободить дважды


Выделенное - совершенно лишний код. Фрее и так внутри проверяет, что ссылка на объект не равна NIL.


 
ZENsan ©   (2008-04-24 11:55) [54]

Мой способ вообще был нормальный:

Obj1 := nil;
Obj2 := nil;
try
 Obj1 := TObj1.Create;
 Obj2 := TObj2.Create;
 ...
finally
 if Assigned(Obj1) then
   FreeAndNil(Obj1);
 if Assigned(Obj2) then
   FreeAndNil(Obj2);
end;


 
ЮЮ ©   (2008-04-24 11:55) [55]

> Ну а такой код-то от чего появился вдруг?

Он появился от того, что появилась проверка if Assigned(Obj1) которая абсолютно ничего не дает.
Что с не, что без неё Obj1.Free сработает абсолютно одинаково.


 
ZENsan ©   (2008-04-24 11:56) [56]

Если исключение будет в сосздании второго объекта...????

Тогда ваша прого просто улетит...


 
ZENsan ©   (2008-04-24 11:57) [57]

"Не факт. Смотри:
Obj1:=TObj.Create;
if Assigned(Obj1) then Obj1.Free;
if Assigned(Obj1) then Obj1.Free;" - ето не мой код...


 
ANB   (2008-04-24 11:58) [58]


> ZENsan ©   (24.04.08 11:55) [54]
> Мой способ вообще был нормальный:
>
> Obj1 := nil;
> Obj2 := nil;
> try
>  Obj1 := TObj1.Create;
>  Obj2 := TObj2.Create;
>  ...
> finally
>  if Assigned(Obj1) then
>    FreeAndNil(Obj1);
>  if Assigned(Obj2) then
>    FreeAndNil(Obj2);
> end;

А я не тебе и писал :).
Тем более твой код - почти такой же как и мой. Кистате, я года 3 назад так же писал, пока Саша Просторов не предложил мне взглянуть на реализацию Фрии :).


 
ZENsan ©   (2008-04-24 11:59) [59]

А я не тебе ;)


 
ZENsan ©   (2008-04-24 12:01) [60]

Ну ка ну ка чё там за фишка про Фрии..
Если вызывать Obj1.Free, когда Obj1 = nil или неинициализирован (локальная переменная в процедуре функции) - то будет исключение 100%...


 
{RASkov} ©   (2008-04-24 12:03) [61]

> [60] ZENsan ©   (24.04.08 12:01)

Проверь:
var B: TObject;
begin
 B:=nil;
 B.Free;
end;


нет никаких АВ :)


 
{RASkov} ©   (2008-04-24 12:09) [62]

> [60] ZENsan ©   (24.04.08 12:01)
> nil или неинициализирован

Дело в том, что это разные вещи и приравнивание переменной Obj1 к nil - тажа самая инициализация по сути.


 
ZENsan ©   (2008-04-24 12:10) [63]

Согласен... Фрии - class procedure.
Но нил я присваиваю именно птоому что объекты когда они локальные в процедурах и функциях могут иметь рандом значения из стека. Поэтому без Obj1 := nil; лучше не жить...

А про фрии, никогда не знал - не полагался никогда на это. предпочитаю 7 раз отмерить - один раз отрезать.


 
ZENsan ©   (2008-04-24 12:11) [64]

Параметры функций/процедур не инициализируются автоматически в Делфи


 
Плохиш ©   (2008-04-24 12:18) [65]


> ZENsan ©   (24.04.08 12:11) [64]
> Параметры функций/процедур не инициализируются автоматически
> в Делфи

Чем дальше в лес, тем толще партизаны...

PS. "Параметры функций/процедур" обычно передаются в эти функции/процедуры, если конечно для них не заданы значения по умолчанию.

PPS. А основы используемого языка программирования всё-таки почитай.


 
ZENsan ©   (2008-04-24 12:19) [66]

Спасибо за справочку {RASkov}, тоесть теперй код такой должен быть:


Obj1 := nil;
Obj2 := nil;
try
Obj1 := TObj1.Create;
Obj2 := TObj2.Create;
...
finally
 FreeAndNil(Obj1);
 FreeAndNil(Obj2);
end;


Ну ваще красота... но я всё же ставлю проверку (ну моразматик я, да :) )..


 
{RASkov} ©   (2008-04-24 12:20) [67]

> [63] ZENsan ©   (24.04.08 12:10)
> Согласен... Фрии - class procedure.

Во первых это статический приватный метод, не классовый.)
Во вторых
> предпочитаю 7 раз отмерить - один раз отрезать.

Тоже не есть верно. Зачем лишние расходы? Можно же еще и так делать и тоже будет верно:
if not Assigned(Ojb) and Obj=nil and (Not assigned(Obj) and Obj=nil) then Obj.Free;
:)


 
ZENsan ©   (2008-04-24 12:21) [68]

const
 Obj: Tobj = nil;

ми про ето не говорим...

Поумничать - это хорошо конечно..


 
ZENsan ©   (2008-04-24 12:22) [69]

{RASkov} - :) это ты круто :)


 
ZENsan ©   (2008-04-24 12:23) [70]

"Во первых это статический приватный метод, не классовый.)" - в делфи это "class procedure/function". (wait)


 
ЮЮ ©   (2008-04-24 12:26) [71]

> [66] ZENsan ©   (24.04.08 12:19)

> finally
> FreeAndNil(Obj1);
> FreeAndNil(Obj2);
> end;


если Obj1 и Obj2 локальные, то нет смфсла в их обNilениее в finally, если &laquo;глобальные&raquo;, т.е. поля объекта, то нет смысла в обNilениее до try.


 
ZENsan ©   (2008-04-24 12:26) [72]

Constructor i Destructor - единственные класс методы до реализации класс методов в делфи начиная по моему с 2005-ого..


 
ZENsan ©   (2008-04-24 12:27) [73]

Если поля обйекта то конечно. Я именно про случай если это локальные переменные не константы..


 
ANB   (2008-04-24 12:30) [74]


>  то нет смфсла в их обNilениее в finally

Вобчем то да. Но могут быть разные глюки потом. Ну его нафиг - мне что жалко один раз выполнить короткое присваивание ? Тем более оно в функции живет.


 
ЮЮ ©   (2008-04-24 12:32) [75]

> Я именно про случай если это локальные переменные не константы&#133


зачем тогда
finally
FreeAndNil(Obj1);
FreeAndNil(Obj2);
end;


так разве менее красиво
finally
Obj1.Free;
Obj2.Free;
end;

P.S. учитывая, что Obj2 := TObj2.Create; часто вызывает исключение, очень вероятно, что при удачном создании обоих объектов упадет с исключением Obj1.Free; и Obj2 останется неосвобожденным :)


 
ЮЮ ©   (2008-04-24 12:36) [76]

> [74] ANB   (24.04.08 12:30)

> Вобчем то да. Но могут быть разные глюки потом


Глюки после смерти? Если они есть, значит проблемы в другом месте кода и это счастье, что тебе удалось уловить их хотя бы опосредованно.


 
Восхищенный   (2008-04-24 12:40) [77]

> ZENsan ©   (24.04.08 12:26) [72]

> Constructor i Destructor - единственные класс методы до реализации класс
> методов в делфи начиная по моему с 2005-ого..

1. Конструктор и деструктор - вообще не классовые методы.

2. Классовые методы реализованы во всех версиях Delphi, начиная аж с 1.

3. В [65] Плохиш дал очень хороший совет. Конечно, можно и дальше переливать здесь из пустого в порожнее, но лучше все же последовать этому совету.


 
{RASkov} ©   (2008-04-24 12:42) [78]

> [70] ZENsan ©   (24.04.08 12:23)

 TObject = class
   constructor Create;
   procedure Free;
   class function InitInstance(Instance: Pointer): TObject;
   procedure CleanupInstance;
   function ClassType: TClass;
   class function ClassName: ShortString;
   class function ClassNameIs(const Name: string): Boolean;
......


Я конечно загнул с приватным :) но не классовый он....


 
Kolan ©   (2008-04-24 12:46) [79]

> но не классовый он&#133

Имхо, слово constructor подразумевает class function, так что, имхо, классовый.


 
{RASkov} ©   (2008-04-24 12:50) [80]

> [79] Kolan ©   (24.04.08 12:46)
> так что, имхо, классовый.

Коструктор, да. Его нужно применять к классу, иначе(если к объекту: Obj.Create;) это не конструктор а вызов метода Create без распределения памяти....

Но я зря его(конструктор) подчеркнул, так как разговор был о Free)



Страницы: 1 2 3 4 5 6 7 8 9 
10 11 12 13 14 15 16 17 вся ветка

Текущий архив: 2008.06.08;
Скачать: CL | DM;

Наверх




Память: 0.64 MB
Время: 0.045 c
2-1210930398
Irina_GR
2008-05-16 13:33
2008.06.08
печать в QReport


2-1210977985
Tomn
2008-05-17 02:46
2008.06.08
ImageList &amp; StringGrid


15-1208952397
Ega23
2008-04-23 16:06
2008.06.08
Можно ли приблизительно оценить длину записи


15-1209297079
Kostafey
2008-04-27 15:51
2008.06.08
С днем рождения ! 27 апреля


15-1209115765
@!!ex
2008-04-25 13:29
2008.06.08
Как работать с libpng???