На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (4) 1 2 [3] 4  все  ( Перейти к последнему сообщению )  
> Свойство-массив. Как правильно написать метод Free?
    Цитата CodeMonkey @
    Позволяет красиво выйти из нескольких циклов, не вводя процедуру или переупорядочивая код.


    Abort в помощь :ph34r:
      Цитата --Ins-- @
      причина должна быть очень веской

      Это верно. Осталось дождаться, когда какой-нибудь косяк из-за отсутствия FreeAndNil не ударит по носу ;)

      Цитата --Ins-- @
      Зря недооцениваешь преимущества Free перед Destroy

      Я ни в коем разе не имел ввиду деструктор! Я сказал: во многих случаях. Случай удаления частично-инициализированного объекта в них, разумеется, не входит.

      Добавлено
      Цитата --Ins-- @
      Abort в помощь

      ИМХО, стрельба из пушки по воробьям.
      Вот когда из нескольких процедур одним махом - это да. А так - зачем? Да и пишется это невнятней goto. (не буду говорить про накладные расходы, просто надо иметь ввиду возможность наличия всяческих утилит диагностики исключений, который вполне могут выполнять кучу работы при raise).
        Цитата CodeMonkey @
        Осталось дождаться, когда какой-нибудь косяк из-за отсутствия FreeAndNil

        У меня был! Был такой код (не мой):
        ExpandedWrap disabled
          firstObject := nil;
          secondObject := nil;
          try
            firstObject := TFirstObject.Create;
            ...
            if ... then
            begin
              secondObject := TSecondObject.Create;
            ...
            end;
            ...
          finally
            firstObject.Free;
            secondObject.Free;
          end;

        Я не вдавался в логику (не было времени, надо было отловить AV), так как работа функции заказчика устраивала. А потому, просто заменил код на:
        ExpandedWrap disabled
          FreeAndNil(firstObject);
          FreeAndNil(secondObject);

        и AV исчезло 8-).
          Цитата CodeMonkey @
          ИМХО, стрельба из пушки по воробьям.


          Ну, а мне видится это как использование инструмента по назначению. Какой смысл инструмента "исключение"? Уйти от сложного кода с условиями. А вместо этого локализовать код обработки внештатной ситуации. Я уже привык, скажем, при использовании WinAPI писать Win32Check вместо тучи проверок условий. Здесь - все тоже самое. Да, goto не использую по религиозным соображениям, потому как вижу более подходящий инструмент, не нарушающий структурность кода.
            В тему:
            http://xkcd.com/386/
            :lool:

            Добавлено
            Цитата --Ins-- @
            Ну, а мне видится это как использование инструмента по назначению.

            Тоже верно. За сим предлагаю тему с goto и закрыть - аргументы все высказали и со всем согласились :)
              Цитата Profi @
              Я не вдавался в логику (не было времени, надо было отловить AV), так как работа функции заказчика устраивала.


              Мда. Если ты на стороне противников FreeAndNil, то довод убедительный, если ты сторонник FreeAndNil, то ты свой игрок в чужой команде :D Я не разобрался и у меня заработало - это значит ты замаскировал ошибку, но не исправил ее. Это все равно, как если бы написал пустой обработчик исключения, и AV тоже перестало бы вылетать. Извини, не наш метод ;)

              Добавлено
              ЗЫ: Я не противник FreeAndNil, я просто не использую его без явной на то необходимости

              Добавлено
              Цитата CodeMonkey @
              За сим предлагаю тему с goto и закрыть


              Согласен, а то может увлечь :D
                Цитата --Ins-- @
                это значит ты замаскировал ошибку

                Смотря что считать ошибкой ;)

                В данном примере могло быть (только например! не надо педантично придираться :) ) так:

                ExpandedWrap disabled
                  firstObject := nil;
                  secondObject := nil;
                  try
                    firstObject := TFirstObject.Create;
                    ...
                    if ... then
                    begin
                      secondObject := TSecondObject.Create;
                    ...
                    end;
                    ...
                    if .... then // редко выполняемое условие
                      secondObject.Free;
                    ...
                  finally
                    firstObject.Free;
                    secondObject.Free;
                  end;


                Да, ошибка. Но FreeAndNil её снимает. Да, возможно, остаётся логическая ошибка. Но не фактическая.

                В любом случае, практика маскировки ошибки не имеет никакого отношения к FreeAndNil vs Free! :angry:
                :D )))
                  Цитата --Ins-- @
                  Я не разобрался и у меня заработало

                  Я не сказал, что я не разобрался. Кстати, не дописал, код такой:
                  ExpandedWrap disabled
                    firstObject := nil;
                    secondObject := nil;
                    for ...
                      try
                        firstObject := TFirstObject.Create;
                        ...
                        if ... then
                        begin
                          secondObject := TSecondObject.Create;
                        ...
                        end;
                        ...
                      finally
                        firstObject.Free;
                        secondObject.Free;
                      end;

                  Сразу кидается в глаза то, что второй объект может быть не создан, но метод Free вызовет Destroy, так как на предыдущей итерации цикла, он был создан и уничтожен, но указатель не был обнулен. Вот и все. Код же, до finally отрабатывается корректно, в нем учитывается создан ли второй объект или нет. Ясное дело, что можно было еще в if добавить блок try finally и уничтожать второй объект в нем через Free. Но из-за нехватки времени, мне было проще заменить две строки, чем переписывать все логику цикла.

                  Добавлено
                  Смотрю какая-то началась на форуме нездоровая тенденция: пытаться уличить оппонента в некомпетентности. Не надо переносить суда привычки с другого форума.
                    Цитата Domino @
                    отступление от классического подхода - уничтожения объектов исключительно в деструкторе

                    Интересно, откуда взялся этот "классический подход" ;) Вот на скорую руку пробежался по classes и controls.pas в D7 и нашел немало мест удаления объектов-полей с занулением ссылок, в частоности в TComponent.Remove происходит удаление списка FComponents при Count=0.
                    Я в своих "супер-пупер" контейнерах при очистке (Clear) также частенько удаляю некоторые объекты либо потому, что они используются не всегда, а от случая к случаю, либо занимают достаточно памяти, а писать для них метод Clear накладно - проще грохнуть и создать заново ;)

                    Цитата CodeMonkey @
                    Цитата leo @
                    Но рекомендовать повсюду совать FreeAndNil вместо Free - это ес-но перебор
                    Ну а почему?

                    Пащиму - патамушта ;)
                    Потому, что использование Free вместо Destroy, во-первых, настоятельно рекомендуется самим Борманом, во-вторых, набрать 4 буквы, да еше и расположенных рядышком на клавиатуре, проше и быстрее, чем 7 ;)
                    А FreeAndNil и набирать дольше и никаких настоятельных рекомендаций по поводу ее использования нет - хочешь юзай, не хочешь не надо, все на твое усмотрение. Разумеется когда нужно обнулить ссылку после Free, то проще юзать FreeAndNil. Поэтому выступать за или против FreeAndNil - просто, как-то глупо ;)

                    PS: Кстати FreeAndNil появилась сравнительно "недавно", по крайней мере в D3 ее не было и люди как то без нее обходились ;) А у меня, например, до сих пор "тащится" парочка долгоиграющих супер-проектов на D3 и поэтому привычка к юзанию FreeAndNil в D7 акуается досадными эрррорами в D3 ;)

                    PPS: Мда, скоко понаписали то, не угнаться за полетом мысли :)

                    Добавлено
                    Цитата Profi @
                    Кстати, не дописал, код такой

                    А правильно было бы как то так:
                    ExpandedWrap disabled
                      for ...
                      begin
                        secondObject:=Nil;    
                        firstObject := TFirstObject.Create;
                        try
                          ...
                          if ... then
                          begin
                            secondObject := TSecondObject.Create;
                            ...
                          end;
                          ...
                        finally
                          firstObject.Free;
                          secondObject.Free;
                        end;
                      end;
                    Сообщение отредактировано: leo -
                      Цитата leo @
                      Разумеется когда нужно обнулить ссылку после Free, то проще юзать FreeAndNil

                      Речь идёт о том, что это не всегда бывает видно. Взяв в привычку повсеместно писать FreeAndNil вы избавляете себя от этих проблем. И не надо ломать голову.
                      Проблема даже в том, что если вы привыкли использовать Free, то во большинстве случаем вам даже не придёт в голову задуматься о том: а не нужен ли здесь FreeAndNil? И вот отсюда-то и лезут проблемы.
                      Как я уже сказал: FreeAndNil - это ремни безопасности. Осталось только это осознать.

                      Цитата leo @
                      Потому, что использование Free вместо Destroy, во-первых, настоятельно рекомендуется самим Борманом

                      Я уже привёл аргументацию, что переход Free -> FreeAndNil имеет бОльшую ценность, чем переход Destroy -> Free. С учётом этого, аргумент отсутствия официального "добро" на FreeAndNil выглядит бледно ;)

                      Цитата leo @
                      акуается досадными эрррорами в D3

                      Не, ну совсем до детского сада-то не стоит опускаться ;) Ничто не мешает добавить FreeAndNil в отдельный модулёк Compatibility.pas. В старших версиях Delphi есть ведь много и других полезных функций, которых нет в D3 - вот и их туда же заодно. Зачем же добровольно лишать себя сладкого?
                        Цитата CodeMonkey @
                        Зачем же добровольно лишать себя сладкого?

                        Чтобы не растолстеть и не потерять тонус ;)

                        Цитата CodeMonkey @
                        Ничто не мешает добавить FreeAndNil в отдельный модулёк Compatibility.pas

                        Открою страшную тайну - я в те стародавние времена своим детским умом допер до "преимуществ" FreeAndNil и юзал собственную аналогичную ф-ю ClearObject, и кстати также совал ее где надо и не надо. Потом как-то все устаканилось и руки сами собой пишут где нужно Free, а где то ClearObject\FreeAndNil

                        Цитата CodeMonkey @
                        Взяв в привычку повсеместно писать FreeAndNil вы избавляете себя от этих проблем. И не надо ломать голову.

                        "Проблема" в том, что твои рекомендации хороши для "детского сада", для вьюношей "пылких со взором горящим", "обдумывающих житье" и т.д. и т.п. А спорить ты пытаешься с людьми, которые (видимо) не одну собаку и не один пуд соли съели и без всякого масла в виде FreeAndNil. И соотв-но менять свои привычки (видимо) не собираются. Поэтому и спор собс-но говоря не уместен. Пиши статейку в FAQ для бегинеров и усё ;)
                        Сообщение отредактировано: leo -
                          Цитата leo @
                          спорить ты пытаешься с людьми, которые (видимо) не одну собаку и не один пуд соли съели и без всякого масла в виде FreeAndNil

                          Я только повторю свой вопрос: ну и что же вы, Destroy-то не используете, где это можно?

                          Цитата leo @
                          И соотв-но менять свои привычки (видимо) не собираются.

                          Об этом я и говорю: что единственная причина использовать Free - это привычка.

                          Цитата leo @
                          Поэтому и спор собс-но говоря не уместен.

                          Да не спорю я ни с кем и уж тем более никого не убеждаю менять свои привычки. Если вы посмотрите, с чего всё началось - меня попросили обосновать эту точку зрения. Всё. Я весь топик повторяю одну и ту же мысль, перекраивая на все лады. Потому что постоянно кто-то влезает и вставляет свои пять копеек (пример с вами: "совать FreeAndNil вместо Free - это ес-но перебор") ;) Вот собственно и всё.
                            Цитата CodeMonkey @
                            Потому что постоянно кто-то влезает и вставляет свои пять копеек


                            Это нормально. Любая мысль, высказанная публично, может быть оспорена.
                              Да не вопрос.
                              Но аргументов-то нет. Видимо, просто не нравится такое мнение - вот нужно обязательно сказать, что это всё зря. Ну а мне это как видится? Что мои слова остались не поняты - значит их нужно сказать по-другому.

                              P.S. Посему, пожалуй, мне стоит закончить.
                              Сообщение отредактировано: CodeMonkey -
                                Цитата CodeMonkey @
                                Я только повторю свой вопрос: ну и что же вы, Destroy-то не используете, где это можно?

                                Я уже объяснил выше: писать Free короче, особенно с учетом того, что она производит проверку объекта на Nil

                                Цитата CodeMonkey @
                                Об этом я и говорю: что единственная причина использовать Free - это привычка

                                С этим никто и не спорит, поэтому чтобы сломать эту привычку нужны достаточно веские аргументы, которых, увы, нет и быть не может ;)

                                Цитата CodeMonkey @
                                Если вы посмотрите, с чего всё началось - меня попросили обосновать эту точку зрения. Всё. Я весь топик повторяю одну и ту же мысль, перекраивая на все лады

                                Началось все с фразы
                                Цитата CodeMonkey @
                                FreeAndNil(Obj); // рекомендуется использовать везде, где это возможно, вместо Obj.Free;

                                Уже к самой формулировке можно придраться. Кем рекомедуется ? Борландом и Ко, мировым дельфийским сообществом ? Или конкретно c великим гуру CodeMonkey, с которым в данном вопросе и на ДК не все согласны ;)
                                И "пять копеек" нужно внимательне рассматривать и цитировать. Пример со мной: я сказал не просто "совать", а "повсюду совать", специально выделив слово "повсюду" - чувствуешь разницу ? Немудрено, что при таком невнимательном и неаккуратном стиле рекомендуется использовать костыли под названием FreeAndNil :D

                                PS: Да, пора завязывать с этим делом. Все все поняли и учли на светлое будущее ;)
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (4) 1 2 [3] 4  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0505 ]   [ 15 queries used ]   [ Generated: 17.05.24, 22:14 GMT ]