Каково основное различие между Свободным и FreeAndNil?
FreeAndNil = свободен + ноль?
Когда я должен использовать Свободный и когда я должен использовать FreeAndNil?
Я не получаю их, когда таращение глаза может кто-то помогать мне.
Заранее спасибо.
См.
И взгляните на реализацию:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
Рассмотрим следующий код:
procedure TForm1.FormCreate(Sender: TObject);
var
bm: TBitmap;
begin
bm := TBitmap.Create;
bm.LoadFromFile('C:\Users\Andreas Rejbrand\Documents\RAD Studio\6.0\Demos\DelphiWin32\VCLWin32\Football\up.bmp');
bm.Free;
if Assigned(bm) then
bm.SaveToFile('C:\Users\Andreas Rejbrand\Desktop\test.bmp')
else
ShowMessage('Cannot save! The bitmap does no longer exist!');
end;
Это создаст ошибку или недопустимое (пустое) растровое изображение на моем рабочем столе, потому что я пытаюсь использовать освобожденный объект. Да, даже несмотря на то, что bm
был освобожден, он все еще «назначен», то есть bm
по-прежнему указывает на адрес памяти, даже если там нет ничего (пригодного для использования). Чтобы преодолеть это, можно установить bm: = nil
в качестве меры предосторожности. Тогда assign (bm)
вернет false, как хотелось бы. Более или менее, FreeAndNil (bm)
является сокращением для bm.Free; bm: = ноль
. Первый оператор освобождает всю память (и ресурсы ОС, время ЦП и т. Д., Используемые объектом), а bm: = nil
устанавливает «указатель» bm
в nil
, так что bm
больше не указывает на то место, где раньше находился объект, но больше не является им.Таким образом, вы (и подпрограммы вроде , назначенные
) не обманетесь, поверив, что все еще существует растровый объект.
Некоторые говорят, что вы всегда должны использовать FreeAndNil (foo)
, а не foo.Free
. А почему бы не? Дополнительная инструкция foo: = nil
, вероятно, не займет слишком много наносекунд для выполнения, и действительно assign (foo) = false
- очень хорошее свойство освобожденного объекта. Но опять же, если вы знаете, что делаете, и знаете, что никогда больше не будете использовать объект foo
после его освобождения, тогда вы можете просто использовать foo.free
. На самом деле, некоторые могут возразить, что во многих случаях (но не во всех) попытка использовать переменную освобожденного объекта сама по себе является ошибкой. (Конечно, бывают случаи, когда вы делаете это намеренно - у вас есть объект foo
, который иногда назначается, а иногда нет.)
Я отвечу иначе.
Возможно, заполнение ссылки на объект nil
после освобождения объекта не всегда является хорошей идеей.
Таким образом, у вас не будет различия между ссылкой, которая никогда не использовалась (и, следовательно, nil
), и ссылкой, которая использовалась, но не должна использоваться в будущем.
Итак, заполняем его магическим числом (аналогично тому, что диспетчер памяти FastMM может делать с содержимым блоков памяти, когда эти блоки освобождаются).
- Иерун
В основном, FreeAndNil устанавливает ссылку на nil и затем освобождает объект. При этом он помечается как неприсвоенный. Поэтому единственная причина, по которой вам нужно использовать FreeAndNil, - это если ваш код собирается повторно использовать ссылку. Если вы находитесь в деструкторе или блоке finally, освобождая объекты, которые вы больше никогда не будете трогать, просто используйте Free.
См. Delphi Memory Management Made Simple для примера, когда я действительно нашел это полезным. Комментарий Mghie внизу также стоит прочитать.
@Bharat, разница между Free
и FreeAndNil
заключается в том, что в дополнение к свободной памяти, используемой объектом, FreeAndNil
устанавливает объектная ссылка на ноль.
вы можете проверить эти ссылки для обсуждения использования Free или FreeAndNil