Эту проблему довольно легко объяснить, и спор вокруг этой проблемы скорее субъективен, чем объективен.Использование FreeAndNil просто не нужно, если ссылка на переменную для освобождаемого объекта выйдет из области видимости:
procedure Test;
var
LObj: TObject;
begin
LObj := TObject.Create;
try
{...Do work...}
finally
//The LObj variable is going out of scope here,
// so don't bother nilling it. No other code can access LObj.
//FreeAndNil(LObj);
LObj.Free;
end;
end;
В приведенном выше фрагменте кода обнуление переменной LObj
будет бессмысленным по причинедано.Однако, если переменная объекта может быть создана и освобождена несколько раз в течение времени жизни приложения, тогда возникает необходимость проверить, действительно ли объект создан или нет.Это простой способ проверить, была ли ссылка на объект установлена на nil
.Чтобы упростить эту настройку до nil
, метод FreeAndNil()
освободит ресурсы и установит для вас nil
.Затем в коде вы можете проверить, создан ли объект с помощью LObj = nil
или Assigned(LObj)
.
Случай использования .Free
или FreeAndNil()
в деструкторах объекта - это серая область, но по большей части, .Free
должен быть безопасным, и добавление ссылок на подобъекты в деструкторе не требуется.Существуют различные аргументы относительно того, как обращаться с исключениями в конструкторах и деструкторах.
Теперь обратите внимание: если вы предпочитаете выбирать .Free
или FreeAndNil()
в зависимости от конкретных обстоятельств, описанных выше,это нормально, но учтите, что цена ошибки из-за , а не обнуления ссылки на освобожденный объект, к которой впоследствии осуществляется доступ, может быть очень высокой.Если впоследствии получить доступ к указателю (объект освобожден, но ссылка не установлена в ноль), может случиться, что вам не повезло, и обнаружение повреждения памяти происходит на расстоянии многих строк кода от доступа к ссылке на освобожденный, но не ноль.Исправление такого рода ошибки может занять очень много времени, и да, я знаю, как использовать FastMM.
Поэтому для некоторых людей, включая меня, это стало привычкой (возможно, ленивой) простообнуляйте все указатели объектов, когда они освобождены, даже если обнуление не является строго необходимым.