2009-05-27 9 views
9

La guida in linea di Delphi dice che è necessario utilizzare Release per rimuovere un modulo dalla memoria. Tuttavia, in molti esempi di forme modali Ho visto questo costrutto:È sicuro usare Free invece di Release per moduli modali in Delphi?

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

Is Free un modo sicuro per distruggere un form modale? Come posso vedere nell'origine di ShowModal, Application.HandleMessage verrà chiamato fino a quando ModalResult non sarà 0. È questo il motivo per cui Free non può interferire con i messaggi Windows in sospeso?

+0

Correlato: http://stackoverflow.com/questions/274523/form-release-nil – mjn

risposta

14

Sì, è sicuro da usare Free dopo una chiamata ShowModal.

I casi in cui è necessario utilizzare Release sono momenti in cui ci si trova nel mezzo di un gestore di eventi (ad esempio, OnClick), in cui l'ulteriore elaborazione successiva all'evento dovrà accedere al modulo. In tal caso, chiamando Release invece invia un messaggio CM_RELEASE, che non libera l'evento fino a quando il gestore di eventi è fatto e il controllo è tornato alla pompa messaggio (ProcessMessages/Application.Run). ShowModal non viene restituito fino a quando il gestore eventi non è terminato e il controllo lo fa eseguire il backup dello stack, quindi chiamare Free in seguito è effettivamente lo stesso posto in cui il messaggio CM_RELEASE verrà elaborato in altro modo.

+0

E fare attenzione a non avere alcuna chiamata Application.ProcessMessages! –

+0

@GerryColl Perché? E dove esattamente? – Bozzy

+0

@Bozzy Se si utilizza 'Rilascio' e quindi si chiama' Application.ProcessMessages', il messaggio 'WM_RELEASE' verrà elaborato e il modulo verrà liberato. La preoccupazione di Gerry è se stai usando Release per rimandare la distruzione e quindi liberare accidentalmente il modulo prima che tu abbia finito con esso. –

3

Assolutamente, ed è anche possibile utilizzare la routine FreeAndNil. La routine FreeAndNil libera l'oggetto solo se non è già nullo, e lo imposta anche su zero dopo il libero. Se chiami gratis direttamente su un oggetto che è già stato liberato, ricevi una violazione di accesso.

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

Small nitpick: Free consente anche di liberare l'oggetto solo se non è già nullo, la seconda parte è quella importante. – mghie

+3

Se MyForm è una variabile locale, l'utilizzo di FreeAndNil() è sicuramente eccessivo. MyForm.Free è sufficiente, infatti MyForm.Destroy funzionerebbe altrettanto bene. –

+1

+ per Allen - L'uso eccessivo di FreeAndNil può nascondere gli errori che sarebbero stati rilevati dal compilatore - non si lamenterà se l'oggetto potrebbe non essere stato inizializzato (solitamente creazione condizionale). Anche questo non risponde alla domanda (SÌ OK). –

4

Dipende. Free nel modulo non chiama i gestori di eventi che esegue Release e tutti i messaggi che potrebbero essere stati inviati al modulo e che sono accodati non verranno elaborati. Pertanto, mentre in molti casi, e probabilmente nella maggior parte dei casi, chiamare Free (o FreeAndNil) funzionerà correttamente, potrebbe verificarsi un comportamento molto strano per motivi apparentemente casuali.

L'alternativa che io suggerirei è nel caso OnClose impostare l'azione per caFree, in questo modo:

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

si può quindi scrivere codice come questo:

TMyForm.Create(nil).ShowModal; 

E voi don Non è necessario liberare il modulo in modo specifico, poiché si libererà automaticamente una volta terminato.

+0

Mi piace la creatività che mostra, ma non la userei mai come il codice mostrato nella domanda è solo il modo idiomatico di farlo - con il tuo codice mi chiedo sempre se il modulo viene liberato correttamente quando inciampo su questo dopo alcuni mesi . – mghie

+0

Meh, qualunque cosa tu ritenga sia la cosa migliore. Tuttavia, questo racchiude interamente la funzionalità del modulo e riduce le possibilità di dimenticare di liberarlo. –

+0

L'impostazione dell'azione su caFree chiama semplicemente Release. Devi stare attento se vuoi accedere alle proprietà del modulo dopo showmodal, nel caso in cui qualcosa (rotto?) Chiama ProcessMessages –

Problemi correlati