Конференция "Прочее" » FreeAndNil
 
  • dmk © (11.12.18 01:02) [20]
    У меня переменные многократно используются. То удаляются, то добавляются. Можно сильно запутаться, а так жесткая напоминалка об обнулении. И от класса объекта не зависит никак. И код сократился в разы - не надо помнить где и какой объект инициализирован.


     //Вариант 0 (Как было)
     gVariant.Free;
     gVariant := nil;
     gObject.Free;
     gObject := nil;
     gGrid.Free;
     gGrid := nil;

     //Вариант 1
     FreeAndNil(@gVarious);
     FreeAndNil(@gObject);
     FreeAndNil(@gGrid);

     //Вариант 2
     gVarious.Free(@gVarious);
     gObject.Free(@gObject);
     gGrid.Free(@gGrid);

     //Вариант 3 (самый удобный)
     Scene.DestroyObjects;
  • Германн © (11.12.18 02:47) [21]

    > dmk ©   (10.12.18 12:26)
    >
    > Всем привет!
    > Возможно ли сделать так, чтобы объект при уничтожении сам
    > себе присваивал nil?

    Никакой объект не имеет "объективной" возможности узнать сколько пользовательская программа сделала на него ссылок. Так что вопрос дурной.
    Вторая "дурность" вопроса заключается в самой "якобы" необходимости обниливать какую-то ссылку.
  • Германн © (11.12.18 02:49) [22]
    Это конечно ИМХО, но вполне обоснованное.
  • Sha © (11.12.18 09:24) [23]
    > Германн ©   (11.12.18 02:49) [22]

    чем-то это мне напоминает борьбу с GOTO )
  • KSergey © (11.12.18 11:26) [24]
    procedure TZObject.Free(AObj: PObject);

    А вот зачем указатель? TObject - уже указатель на объект же. Точно требуется еще и указатель на этот указатель?
  • KSergey © (11.12.18 11:27) [25]
    Если хочется переприсвоить значение самой переданнйо переменной - её просто надо передать по ссылке, т.е.

    procedure TZObject.Free(var AObj: TObject);

    Как-то оно прямее, понятнее, добрее
  • dmk © (11.12.18 11:49) [26]
    >А вот зачем указатель?
    У меня массив указателей на переменные, а не на адреса объектов.
    Инчае в параметрах придется писать обертку PObject(MyObjectType),
    а он не пропустит, т.к. строгая типизация, а указатели пропускает.
    Я уже все варианты перепробовал.
    Так проще всего:

    type
     PVar = ^TVar;
     TVar = Pointer;

    procedure TZObject.Free(AVar: TVar);
    begin
     inherited Free;

     //Очистка переменной
     if (AVar <> nil) then
       if (PVar(AVar)^ <> nil) then PVar(AVar)^ := nil;
    end;


    и вызов
    FObjects[i].Free(@FObjects[i]^);
    Все внешние переменные прилинкованные к массиву обнуляются и освобождаются.
  • dmk © (11.12.18 11:55) [27]
    Добавляем ссылку на переменную:
    Scene.AddObject(@gObject);
    Удаляем ссылку из массива указателей^
    FObjects[i].Free(@FObjects[i]^);
    Освобождаем объект и очищаем переменную:
    FreeAndNil(@gVarious);

    Очистка:
    procedure FreeAndNil(AVar: TVar);
    begin
     if (AVar <> nil) then if (PVar(AVar)^ <> nil) then
     begin
       PObject(AVar)^.Free;
       PVar(AVar)^ := nil;
     end;
    end;
  • dmk © (11.12.18 12:08) [28]
    У меня массив не
    FObjects: array of TZObject, а
    FObjects: array of PZObject;
    Ссылки на переменные и на другие массивы, которые уже TZObject.
  • KSergey © (11.12.18 12:35) [29]
    > dmk ©   (11.12.18 11:49) [26]
    > Все внешние переменные прилинкованные к массиву обнуляются и освобождаются.

    Чего??

    > dmk ©   (11.12.18 12:08) [28]
    > У меня массив не
    > FObjects: array of TZObject, а
    > FObjects: array of PZObject;

    Это понятно, про это и вопрос.

    > dmk ©   (11.12.18 12:08) [28]
    > Ссылки на переменные и на другие массивы, которые уже TZObject.

    Но зачем? вот что мне не понять.
    Обратите внимание: в VCL не смотря на то, что есть понятие "владелец объекта", который этот объект удаляет, кстати, совершенно успешно, и при всём при этом в VCL никаких PObject - нет совершенно. Ибо не нужны они. Правда-правда.
  • KSergey © (11.12.18 12:38) [30]
    > dmk ©   (11.12.18 11:55) [27]

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

    Это уже не говоря про то, что FreeAndNil() есть штатная же, и она иначе несколько устроена в смысле типов
  • dmk © (11.12.18 13:10) [31]
    >Если бы вы обрисовали задачу, которую всеми этими изворотами решаете -
    >уверен, вам бы подсказали более прямой и понятный путь решения задачи.
    В [18] описаны варианты создания объектов. Из файла [1], процедурная генерация [2], генерация массивов [3].
    Над объектами проводится куча действий:
    1. Трансформация
    2. Перекраска
    3. Текстурирование
    4. Слияние
    5. Отрисовка
    и т.д. и т.п.
    Действия в цикле однотипные, но доступ к объектам или через массив ссылок или через переменную. Нужно и так и так. Кол-во объектов может быть и сотни и тысячи и десятки тысяч. Переменных может быть также несколько десятков. Зачем мне листинги с удалением персональных переменных? Проще добавить в массив и потом махом все удалить. Поведение объектов хаотичное. Это 3D-сцена в общем. По ссылкам в массиве удобно все удалить или удалить выборочно.
  • KSergey © (11.12.18 14:58) [32]
    Из написанного вами вот что не понятно: зачем массив указателей на (сслыки) объекты?
    Да, я умышлено пишу "ссылки на объекты", ибо TObject - эти именно ссылка на объект по своей сути, ну или, более честно, указатель. Уже указатель!

    > Действия в цикле однотипные, но доступ к объектам или через массив ссылок или через переменную.

    Это вы так сделали, и это из кода видно.
    Но зачем? смысл какой всего этого? зачем вам ссылки непременно понадобилось в разных местах хранить?
    Кстати, почему бы не хранить целочисленные индексы в массиве объектов? зачем указатели?
    Индексы имеют тот плюс, что их можно контролировать. А указатели - нельзя, т.к. нет возможности достоверно узнать указывает указатель на валидное значение или на невалидное в памяти.
  • dmk © (11.12.18 15:01) [33]
    >Но зачем? смысл какой всего этого?
    Вот так это визуально выглядит:
    https://yadi.sk/i/tU7G3tfHrl4hBQ
    Сцена одна, а объекты из разных мест появляются.
  • KSergey © (11.12.18 16:03) [34]
    Не понятно (мне), но определённо красиво! )

    PS
    Расширение для файла .obj - режет глаз, конечно (ибо уже имеет своё устоявшееся значение в компьютерном мире). Но чем заменить - не знаю.
  • dmk © (11.12.18 16:15) [35]
    >.obj - режет глаз
    Зато бесплатно. Это открытый формат. Бесплатных очень мало.
  • ухты © (11.12.18 20:09) [36]

    > массив указателей на переменные
    еще чудесатее
    а вот этот новый фри скорее всего напрочь и эту переменную стирает, прям из кода))
  • FreeAndNil © (11.12.18 20:25) [37]
    По ссылкам в массиве удобно все удалить или удалить выборочно.

    а теперь я начинаю хотеть хранить ссылки на чудесный самоубивающийся класс в свойствах другого класса.

    привет, тебе, пернатый архитектор у которого не болит голова.
  • sniknik © (11.12.18 20:40) [38]
    > У меня массив указателей на переменные, а не на адреса объектов.
    повторю ранее говорившееся, читай внимательно - переменная объекта, это уже указатель.
    нет смысла в указателе на указатель, первый и так прекрасно на объект указывает, без дополнительных посредников.


    > Так проще всего:
    > type
    >   PVar = ^TVar;
    >   TVar = Pointer;
    >  
    > procedure TZObject.Free(AVar: TVar);
    > begin
    >   inherited Free;
    >  
    >   //Очистка переменной
    >   if (AVar <> nil) then
    >     if (PVar(AVar)^ <> nil) then PVar(AVar)^ := nil;
    > end;

    ... если нормально, то как мне кажется попроще, а делать будет то же самое.
    TObject вместо TVar чтобы, ты сам упоминал, без приведений типов, сойдет для всех потомков
    procedure TZObject.Free(var AVar: TObject);
    begin
      inherited Free;
      AVar:= nil;
    end;

  • Pavia © (11.12.18 20:52) [39]

    > Прикольно, трупы сами себе могилу роют.

    В нормальных языках это давно так реализовано.


    > Возможно ли сделать так, чтобы объект при уничтожении сам
    > себе присваивал nil?
    > Или надо FreeAndNil использовать?

    Нельзя.
    Embarcodere уже который год тянут кота за яйца, но автосборку мусора сделать не могут.
    Да проще свой препроцессор написать.
Есть новые Нет новых   [134427   +34][b:0][p:0.001]