Который предпочтителен: Свободный или FreeAndNil?

Каково основное различие между Свободным и FreeAndNil?

FreeAndNil = свободен + ноль?

Когда я должен использовать Свободный и когда я должен использовать FreeAndNil?

Я не получаю их, когда таращение глаза может кто-то помогать мне.

Заранее спасибо.

47
задан Andreas Rejbrand 2 July 2010 в 23:20
поделиться

4 ответа

См.

И взгляните на реализацию:

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 , который иногда назначается, а иногда нет.)

43
ответ дан 26 November 2019 в 19:45
поделиться

Я отвечу иначе.

Возможно, заполнение ссылки на объект nil после освобождения объекта не всегда является хорошей идеей.

Таким образом, у вас не будет различия между ссылкой, которая никогда не использовалась (и, следовательно, nil ), и ссылкой, которая использовалась, но не должна использоваться в будущем.

Итак, заполняем его магическим числом (аналогично тому, что диспетчер памяти FastMM может делать с содержимым блоков памяти, когда эти блоки освобождаются).

- Иерун

8
ответ дан 26 November 2019 в 19:45
поделиться

В основном, FreeAndNil устанавливает ссылку на nil и затем освобождает объект. При этом он помечается как неприсвоенный. Поэтому единственная причина, по которой вам нужно использовать FreeAndNil, - это если ваш код собирается повторно использовать ссылку. Если вы находитесь в деструкторе или блоке finally, освобождая объекты, которые вы больше никогда не будете трогать, просто используйте Free.

См. Delphi Memory Management Made Simple для примера, когда я действительно нашел это полезным. Комментарий Mghie внизу также стоит прочитать.

18
ответ дан 26 November 2019 в 19:45
поделиться

@Bharat, разница между Free и FreeAndNil заключается в том, что в дополнение к свободной памяти, используемой объектом, FreeAndNil устанавливает объектная ссылка на ноль.

вы можете проверить эти ссылки для обсуждения использования Free или FreeAndNil

6
ответ дан 26 November 2019 в 19:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: