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

Вниз

Вызов Free внутри класса   Найти похожие ветки 

 
Kerk ©   (2014-05-13 21:27) [0]

Я придерживаюсь мнения, что в подавляющем большинстве случаев вызов Free внутри самого класса (то есть self.Free) - признак плохого кода. Мне отвечают, что внутри форм это иногда нужно. Но тем не менее мне кажется, что внутри форм в таких случаях вместо Free нужно вызывать Release. То есть я продолжаю стоять на позиции, что self.Free - это в общем случае что-то нехорошее.

Вы как думаете? Врядли удастся меня переубедить, так что такую цель ставить не стоит. Мне интересно посмотреть какие вообще бывают мнения.


 
Dimka Maslov ©   (2014-05-13 21:34) [1]

Тем не менее потоки сами себя могут прибивать, и интерфейсы тоже в ответ на _Release. Больше нигде я до такого не докатывался.


 
Kerk ©   (2014-05-13 21:42) [2]

Интерфейсы да, про них я забыл, 100% легальная ситуация.
И потоки с FreeOnTerminate.

Хорошие примеры. Ну и это по-моему всё?


 
jack128_   (2014-05-13 22:14) [3]


> Я придерживаюсь мнения, что в подавляющем большинстве случаев
> вызов Free внутри самого класса (то есть self.Free) - признак
> плохого кода

Я тоже так считаю. Зачем вызывать Free если достаточно Destroy.


 
Дмитрий СС   (2014-05-13 22:15) [4]

Application разве не сам себя ?


 
DVM ©   (2014-05-13 22:30) [5]


> Дмитрий СС   (13.05.14 22:15) [4]
> Application разве не сам себя ?

нет, он уничтожается в секции финализации модуля Vcl.Controls


 
Дмитрий СС   (2014-05-13 23:17) [6]


> DVM ©   (13.05.14 22:30) [5]

Подумал об этом сразу после нажатия кнопки "Добавить". Поторопился.


 
Игорь Шевченко ©   (2014-05-14 10:30) [7]


> Я придерживаюсь мнения, что в подавляющем большинстве случаев
> вызов Free внутри самого класса (то есть self.Free) - признак
> плохого кода


а можно пример привести, а то что-то не могу придумать ситуацию, когда это может встретиться.
_Release у интерфейсов и .Release у TForm - это тот самый Free, только с другой стороны.

Насколько я тебя понял, ты считаешь, что в правильном коде всегда есть кто-то свыше, который определяет, кому когда жить и кому когда умирать, верно ?


 
Kerk ©   (2014-05-14 10:39) [8]

Игорь Шевченко ©   (14.05.14 10:30) [7]

> Насколько я тебя понял, ты считаешь, что в правильном коде
> всегда есть кто-то свыше, который определяет, кому когда
> жить и кому когда умирать, верно ?

Да, кто создал, тот и убьет. Самоубийство интерфейса при обнулении счетчика ссылок - это все-таки особый случай.

Ну и Release - это не то же самое, что Free. Release - это убийство через очередь сообщений.


 
Юрий Зотов ©   (2014-05-14 13:41) [9]

> Kerk ©   (13.05.14 21:27)

Полностью согласен. А то, что "внутри форм это иногда бывает нужно" - бред. Потому что существует специально под то и заточенный Release - по сути, тот же Free, но безопасный.

Ром, предложи апологетам такой примерчик:

procedure TForm1.Foo;
begin
  Bar;
  Любое обращение к любому собственному полю;
end;

procedure TForm1.Bar;
begin
  Что-то делаем;
  Free;
end;


 
Ega23 ©   (2014-05-14 14:14) [10]


> Ром, предложи апологетам такой примерчик:


На первый взгляд всё штатно должно отработать, нет?


 
sniknik ©   (2014-05-14 14:18) [11]

> На первый взгляд всё штатно должно отработать, нет?
на "Любое обращение к любому собственному полю;" будет AV, объекта/формы уже нет, а код еще выполняется.


 
Sha ©   (2014-05-14 14:37) [12]

> Юрий Зотов ©   (14.05.14 13:41) [9]

на всякий Release найдут Application.ProcessMessages )


 
Ega23 ©   (2014-05-14 15:06) [13]


>  объекта/формы уже нет, а код еще выполняется.



procedure TForm13.Bar;
begin
 Free;
end;

procedure TForm13.Button1Click(Sender: TObject);
begin
 Bar;
 ShowMessage(Caption);
end;


Всё показывается.

Не, ежели многопоточность, то да поведение непредсказуемо. А в целом - от менеджера памяти зависит.


 
Inovet ©   (2014-05-14 15:11) [14]

> [13] Ega23 ©   (14.05.14 15:06)
> Всё показывается.

Останки?


 
sniknik ©   (2014-05-14 15:13) [15]

Caption не настоящий объект... к нему обращение идет через сообщения/хендл, а не начиная "от объекта".


 
Ega23 ©   (2014-05-14 15:17) [16]


> Caption не настоящий объект... к нему обращение идет через
> сообщения/хендл, а не начиная "от объекта".


В [9] постановка вопроса довольно чёткая. Сaption - одно из полей данного объекта.
Память считается свободной, но нулями-то её никто не затирал, верно?


 
sniknik ©   (2014-05-14 15:17) [17]

... а я тем не менее получил AV на таком [13] коде. D7


 
sniknik ©   (2014-05-14 15:19) [18]

> Память считается свободной, но нулями-то её никто не затирал, верно?
нет гарантий, и главное тут не сами данные заголовка, а а адрес self который уже не валидный.


 
Ega23 ©   (2014-05-14 15:33) [19]


> нет гарантий, и главное тут не сами данные заголовка, а
> а адрес self который уже не валидный.
>  


От менеджера памяти зависит.
Гарантий, ясен пень, нет.


 
Cobalt ©   (2014-05-14 15:45) [20]

Что-то я не понял про интерфейсы - это когда это они сами себя убивают?

На мой взгляд, "_Release" - это своеобразный Free.
Условный такой.


 
han_malign   (2014-05-14 16:55) [21]


>  это в общем случае что-то нехорошее

- даже законодательство на нашей стороне... И религия утверждает, что само[цензура]ство - грех...

> предложи апологетам такой примерчик

- и извечный вопрос - почему Assigned() = true...


> Интерфейсы да, про них я забыл, 100% легальная ситуация.

- как показывает MTA - этот трюк с инкапсуляцией логики последней ссылки - таки ущербен и требует хорошего понимания вопроса...
А 100% легальный - это C++11 unique_ptr/shared_ptr - которые являются одноместым контейнером с явным управлением временем жизни элемента(владельцем ссылки)...


> внутри форм в таких случаях

- все-таки нужно вызывать Close, т.к. в большинстве случаев именно оно приводит к выходу из dispatch-цикла(ShowModal) с последующим явным освобождением экземпляра во внешнем контексте...


> И потоки с FreeOnTerminate.

- а это по большому счету не является self.free - т.к. это по сути передача ресурса в область видимости функции потока...
Кривизна(в старых версиях VCL) и навороченность реализации этой простой амбулы, связанная с гонкой основного и целевого потока - это отдельный вопрос...


> В [9] постановка вопроса довольно чёткая.

procedure TForm1.Button1Click(Sender: TObject);
begin
  Release;
  Application.ProcessMessages;
  Release;
end;


 
Leonid Troyanovsky ©   (2014-05-14 17:42) [22]


> Kerk ©   (13.05.14 21:27)

>  Но тем не менее мне кажется, что внутри форм в таких случаях
> вместо Free нужно вызывать Release. То есть я продолжаю
> стоять на позиции, что self.Free - это в общем случае что-
> то нехорошее.

Здесь как-то обсуждали похожие темы.
Например, http://www.delphimaster.net/view/2-1192180654

Общественность пришла к выводу, что суицидальные объекты
трудны для чтения-восприятия-сопровождения и др.

IMHO, 99% подобных потребностей могут быть удовлетворены
за счет использования простой (вполне академичной) схемы:

try
 foo.smthng; // при вызове метода объект может стать негоден к жизни
except
 on E: EFreeObject do
   begin
      foo.Free;
      raise; // дальнейшее выполнение кода с foo не имеет смысла
  end;
end;

--
Regards, LVT.


 
Rouse_ ©   (2014-05-14 19:45) [23]

Бывают ситуации, когда нужен вызов именно Free в форме, а не Release, в частности это связано с использованием категорически не желательной процедуры ProcessMessage.
Мы в свое время как-то поздно пришли к этому что GUI нить должна использоваться только для взаимодействия с пользователем, а все тяжелое нужно выносить в допнити, в итоге понагавнокодили в свое время (лет эдак 7-8 назад) распихав везде пресловутый ProcessMessage, вот все еще боремся с последствиями...


 
Rouse_ ©   (2014-05-14 19:48) [24]

ЗЫ: в том смысле что я не утверждаю что вызов Free допустим, как раз наоборот, но... в качестве вынужденной меры (как костыль) к сожалению иногда неизбежен.


 
Rouse_ ©   (2014-05-14 19:51) [25]

Кстати последний проект я с Олегом писал строго по идеологии и ни одного вызова ProcessMessage там нет - код можно сказать идеально чистый, все грамотно и по полочкам разложено.
А ProcessMessage - зло как есть (я его лично считаю за гавнокод, но это только мое мнение) :)


 
Дмитрий СС   (2014-05-14 20:01) [26]

Любое использование или только в качестве незамерзайки?


 
Rouse_ ©   (2014-05-14 20:02) [27]


> Дмитрий СС   (14.05.14 20:01) [26]
> Любое использование или только в качестве незамерзайки?

Любое.
Приложение само крутит ЦВС, не нужно ему помогать в этом.
Если тебе потребовалось крутануть очередной цикл - ты что-то сделал не так.


 
Германн ©   (2014-05-15 02:11) [28]


> Rouse_ ©   (14.05.14 19:51) [25]
>
> Кстати последний проект я с Олегом писал строго по идеологии
> и ни одного вызова ProcessMessage там нет - код можно сказать
> идеально чистый, все грамотно и по полочкам разложено.

Создаётся впечатление, что ты (вы) только и думаете как бы избавиться от Дельфи оставаясь на ней. Полный и безоговорочный запрет на использование ProcessMessages напоминает либо дискриминацию по неизвестным мне причинам, либо борьбу с нечистой силой.
Конечно ИМХО.


 
han_malign   (2014-05-15 09:21) [29]


> Полный и безоговорочный запрет на использование ProcessMessages
> напоминает либо дискриминацию по неизвестным мне причинам,
>  либо борьбу с нечистой силой.

- слишком много побочных эффектов при нулевой ценности - нечистая сила и есть...

максима:
- единственно применение - это костыль - для тех кому неведомо понятие "конечный автомат", плохо понятен принцип кооперативной многозадачности, а асинхронные операции вызывают ужас...
Если запихивать все в один поток - то по фен-шую - надо бить все тяжелые вычисления на кванты конечного автомата и отрабатывать в Application.OnIdle

но если таки в лом;
- надо четко осознавать, что метод вызывающий Application.ProcessMessages() - не реентерабелен в самом широком смысле, и должен быть синглетоном...

Кроме шуток - я реально ловил переполнение стека в корпоративном говнокоде - после чего таки сделал тотальный поиск, и удалил чуть меньше 300 вызовов в 50-ти файлах.
Причем никаких дополнительных действи не понадобилось - оно там было от балды - кто-то считал это хорошим тоном...
Поэтому надо налаживать выпуск детских погремушек с надписью "Application.ProcessMessages() - это Вселенское Зло!"

А ноги скорее всего растут из OWL для Windows 1.0-3.1 - где квант отдавался как раз вызовом GetMessage()/PeekMessage()...


 
sniknik ©   (2014-05-15 09:54) [30]

> - надо четко осознавать
что применять можно что угодно, главное ко времени и по месту.

> Поэтому надо налаживать выпуск детских погремушек с надписью "Application.ProcessMessages() - это Вселенское Зло!"
100% борьба с "нечистой силой". притом с желанием применить на безответных не могущих еще думать/возразить... путем внедрения догмы.


 
имя   (2014-05-15 10:01) [31]

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


 
han_malign   (2014-05-15 10:05) [32]


> только и думаете как бы избавиться от Дельфи оставаясь на ней.

- а ты поищи в VCL - насколько активно там используется Application.ProcessMessages()...
И как бы... - варианта всего два с половиной:
- внешний "прогресс"(чужой цикл с callback)
-- ожидание внешнего асинхронного события
- актуализация состояния компонент с асинхроным конечным автоматом(в которых используется PostMessage() для изменения состояния)



Страницы: 1 вся ветка

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

Наверх




Память: 0.56 MB
Время: 0.007 c
2-1385580807
SKIPtr
2013-11-27 23:33
2014.12.14
запись параметров в ini файл


6-1274251810
Dmitriy
2010-05-19 10:50
2014.12.14
контроль (учет) трафика WinInet


15-1397669855
Rouse_
2014-04-16 21:37
2014.12.14
Задачка для разминки мозга


3-1301462832
vlgrig1961
2011-03-30 09:27
2014.12.14
HELP!!!Странная сортировка при GROUP BY


3-1301760583
worldmen
2011-04-02 20:09
2014.12.14
Запрос списка уволенных