Конференция "Основная" » Отложенное освобождение объектов
 
  • ggg (19.06.08 19:39) [0]
    У меня в программе некоторые объекты имеют счетчик использования. Сделано это для того, что бы они не были удалены до того, когда на них перестанут ссылаться другие объекты.
    Сначала пробывал добавить следующий код в деструктор:

    destructor TGraphicObject.Destroy;
    begin
       if UseCount > 0 then
         begin
           FMustBeFree := true;
           Exit;
         end;
    ...



    Но практически сразу же получал AV.
    Поэтому создал метод Free;


    procedure TGraphicObject.Free;
    begin
     if Assigned(Self) then
       if UseCount > 0 then
         FMustBeFree := true
       else
         inherited; // или Destroy, не важно
    end;



    Пока вроде бы проблем не наблюдается, но как-то беспокойно на душе :)
    Собственно вопросы:
    1) Destroy в любом случае удаляет объект, даже если там стоит Exit и не вызывается inherited?
    2) Метод Free не помечен как virtual, соответсвенно и мой метод не может быть отмечен как override. Безопасно ли использовать такой способ? Или правильней будет создать некий MyFreeMethod, где будет проверяться FUseCount и вызываться Free?
  • Поросенок Винни-Пух © (19.06.08 20:04) [1]
    procedure TGraphicObject.Free;
    begin
    if Assigned(Self) then

    гениально.
  • Поросенок Винни-Пух © (19.06.08 20:05) [2]
    А оунер этого волшебного объекта в курсе что кто-то там что-то там считает?

    :)
  • Игорь Шевченко © (19.06.08 20:06) [3]
    тебе надо посмотреть, как работает TInterfacedObject._Release - оно так примерно и делает, если ссылок 0, то вызывает Destroy

    Или переопределить метод FreeInstance
  • Игорь Шевченко © (19.06.08 20:06) [4]
    Поросенок Винни-Пух ©   (19.06.08 20:04) [1]


    > if Assigned(Self) then
    >
    > гениально.


    Тебе никогда не встречался Self=nil ?
  • Поросенок Винни-Пух © (19.06.08 22:30) [5]
    Мне интересно куда он там мог деться в первой же строчке собственного метода, что его проверяют на нил
  • Поросенок Винни-Пух © (19.06.08 22:34) [6]
    Сделано это для того, что бы они не были удалены до того, когда на них перестанут ссылаться другие объекты.

    То есть есть самодельный механизм подсчета и зачем-то переделываются методы дестрой и фри.

    А для чего? Для того, чтобы можно было в любой строчке собственного когда неглядя вызвать фри объекта, не опасаясь что он будет удален если на него есть ссылки?
    А не логичнее ли вызывать фри по условию, если уж автору известно есть ссылки или нет их?
  • Loginov Dmitry © (19.06.08 22:53) [7]
    > Мне интересно куда он там мог деться в первой же строчке
    > собственного метода, что его проверяют на нил



    var
     g: TGraphicObject;
    begin
     g := nil;
     g.Free;
    end;



    Что произойдет в
    g.Free

    , если
    if Assigned(Self)

    не делать?
  • Поросенок Винни-Пух © (19.06.08 22:56) [8]
    ты во внутрь самого фри не попадешь при таком раскладе
  • Loginov Dmitry © (19.06.08 23:00) [9]
    > ты во внутрь самого фри не попадешь при таком раскладе


    Free - это статический метод (фактически обычная процедура). Почему же я в нее не попаду?
  • Anatoly Podgoretsky © (19.06.08 23:09) [10]
    > Loginov Dmitry  (19.06.2008 22:53:07)  [7]

    А зачем его делать?
    Советую взглянуть генофонд или прочитать справку.
  • Поросенок Винни-Пух © (19.06.08 23:14) [11]
    Что произойдет в g.Free, если if Assigned(Self) не делать?

    Произойдет то же самое, что происходит если делать if Assigned(Self)

    g := nil;
    g := T...Create();
    g.Free;
  • Поросенок Винни-Пух © (19.06.08 23:15) [12]
    Нагляднее так:

    type
    ttt = class
     procedure test;
    end;

    procedure ttt.test;
    begin
     if Assigned(Self) then ShowMessage('yes') else ShowMessage('no');
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var t : ttt;
    begin
    t := nil;
    t := ttt.Create;
    t.Free;
    t.test;
    end;
  • Loginov Dmitry © (19.06.08 23:16) [13]
    > А зачем его делать?


    У автора реализован собственный метод Free. В нем выполняется проверка if Assigned(Self). Что произойдет в g.Free (из [7]), если if Assigned(Self) (в TGraphicObject.Free) не делать?
  • Eraser © (19.06.08 23:18) [14]
    > [0] ggg   (19.06.08 19:39)


    > if Assigned(Self) then
    >   if UseCount > 0 then

    в данном коде смущает то, что большое количество вложенных условий делает код запутанным.
    imho, уместнее
    if not Assigned(Self) then
     Exit;

  • Поросенок Винни-Пух © (19.06.08 23:20) [15]
    У автора реализован собственный метод Free. В нем выполняется проверка if Assigned(Self). Что произойдет в g.Free (из [7]), если if Assigned(Self) (в TGraphicObject.Free) не делать?

    произойдет все то же самое если её делать.
  • Loginov Dmitry © (19.06.08 23:24) [16]
    > imho, уместнее
    > if not Assigned(Self) then
    > Exit;


    имхо, нагляднее так:
    procedure TGraphicObject.Free;
    begin
     if Assigned(Self) then
     begin
       if UseCount > 0 then
         FMustBeFree := true
       else
         inherited; // или Destroy, не важно
     end;
    end;



    Но у каждого будет свое имхо и спорить, имхо, бессмысленно.
  • Loginov Dmitry © (19.06.08 23:26) [17]
    > произойдет все то же самое если её делать.


    Для чего тогда, по Вашему, в TObject.Free() реализована такая же проверка?
  • Поросенок Винни-Пух © (19.06.08 23:29) [18]
    я ж нарисовал пример в котором assigned рапортует "yes"
    и типа после этого метод уверен, что можно что-то там делать.
  • Loginov Dmitry © (19.06.08 23:55) [19]
    > я ж нарисовал пример в котором assigned рапортует "yes"
    > и типа после этого метод уверен, что можно что-то там делать.


    совать во Free() битые ссылки - ситуация ненормальная и естественно карается. А вот вызов TObject(nil).Free - это обычное дело, и без проверки на nil не обойтись.
 
Конференция "Основная" » Отложенное освобождение объектов
Есть новые Нет новых   [134491   +12][b:0][p:0.001]