Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.06.08;
Скачать: [xml.tar.bz2];

Вниз

Освобождение ресурса в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.62 MB
Время: 0.072 c
2-1210671467
snake-as
2008-05-13 13:37
2008.06.08
Не могу сохранить таблицу в БД


4-1190892438
apic
2007-09-27 15:27
2008.06.08
hIcon


15-1208933925
REA
2008-04-23 10:58
2008.06.08
Договор с работодателем


2-1211026843
Ultimate
2008-05-17 16:20
2008.06.08
Загрузка определенной строки из файла


2-1210761585
MZG
2008-05-14 14:39
2008.06.08
Программа и память





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