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

Вниз

Вызов 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.003 c
15-1399904738
Астахов Сергей
2014-05-12 18:25
2014.12.14
Экспорт данных в OpenOffice


15-1400163635
RDen
2014-05-15 18:20
2014.12.14
firefox при запуске открывает http://trafmarket.ru/install


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


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


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





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