Безопасно ли использовать Free вместо Release для модальных форм в Delphi?

в онлайн-справке Delphi говорится, что Release следует использовать для удаления формы из памяти. Однако во многих примерах для модальных форм я видел эту конструкцию:

MyForm := TMyForm.Create(nil);
try
  MyForm.ShowModal;
finally
  MyForm.Free;
end;

является ли Free безопасным способом уничтожения модальной формы? Как я вижу в источнике для ShowModal, приложение.Handlemessage в будет называться, пока ModalResult не 0. Это причина, почему Free не может вмешиваться в ожидающие сообщения windows?

3 ответов


да, безопасно использовать Free после ShowModal звонок.

случаи, когда вам нужно использовать Release времена, когда вы находитесь в середине обработчик событий (например, OnClick), где дальнейшая обработка после мероприятия будет получить доступ к форме. В таком случае звоню Release вместо сообщений a CM_RELEASE сообщение, которое не освобождает событие, пока обработчик событий не будет выполнен, и управление не вернется в насос сообщений (ProcessMessages/Application.Run). ShowModal не возвращается до обработчик событий завершен, и control создает резервную копию стека, поэтому вызов Free потом-это фактически то же самое место, где CM_RELEASE сообщение будет обработано в противном случае.


это зависит. Freeing форма не вызывает обработчики событий, которые Release делает, и любые сообщения, которые могли быть отправлены в форму и поставлены в очередь, не будут обработаны. Так что, во многих и, возможно, в большинстве случаев, вызывая Free (или FreeAndNil) будет работать нормально, это может привести к очень странному поведению по кажущимся случайным причинам.

альтернатива, которую я бы предложил, в событии OnClose устанавливает действие в caFree, например:

procedure FormClose(Sender : TObject; Action : TCloseAction)
begin
  Action := caFree;
end;

вы можете затем напишите код следующим образом:

TMyForm.Create(nil).ShowModal;

и вам не нужно освобождать форму специально, так как она освободится сама, когда это будет сделано.


абсолютно, и вы также можете использовать процедуру FreeAndNil. Процедура FreeAndNil освободит объект только в том случае, если он еще не равен нулю, а также установит его равным нулю после освобождения. Если вы вызываете free непосредственно на объект, который уже был освобожден, вы получаете нарушение доступа.

MyForm := TMyForm.Create(nil); 
try 
  MyForm.ShowModal; 
finally 
  FreeAndNil(MyForm); 
end;