Quelle est la bonne façon de créer dynamiquement/version runtime formes?
J'essaie toujours de créer mes Applications avec l'utilisation de la mémoire dans l'esprit, si vous n'avez pas besoin alors de ne pas créer c'est la façon dont je regarde.
De toute façon, prendre ce qui suit comme exemple:
Form2:= TForm2.Create(nil);
try
Form2.ShowModal;
finally
Form2.FreeOnRelease;
end;
En fait, je pense Form2.Détruire est probablement la meilleure option, ce qui m'amène à ma question..
Quelle est la différence entre un appel:
Form2.Destroy;
Form2.Free;
Form2.FreeOnRelease;
Ils font tous le même travail ou un travail similaire, à moins que quelque chose m'échappe.
Et aussi lorsque les ci-dessus? Évidemment, lors de la libération d'un Objet je le comprends, mais dans certaines situations, est Destroy
mieux que Free
par exemple?
lire sur
appel Gratuit vérifie si l'objet n'est pas Nul, et ensuite appeler Détruire en conséquence. Il est sûr. l'appel de Détruire ne vérifie pas si l'objet est nulle, de sorte qu'il pourrait déclencher VA.
TObject.Free
, TObject.Destroy
appel Gratuit vérifie si l'objet n'est pas Nul, et ensuite appeler Détruire en conséquence. Il est sûr. l'appel de Détruire ne vérifie pas si l'objet est nulle, de sorte qu'il pourrait déclencher VA.
OriginalL'auteur | 2011-06-10
Vous devez vous connecter pour publier un commentaire.
C'est un code-odeur, parce que
Form2
est probablement le mondial, l'IDE a généré variable qui serait normalement tenir une IDE crééTForm2
. Probablement vous voulez utiliser une variable locale, et l'autre avec un meilleur nom. Ce n'est pas nécessaire d'avoir une erreur, juste un code-odeur.Utilisation
Form2.Free
, parce qu'il appelleDestroy
de toute façon. Vous pouvez CTRL+Cliquez sur le nom (Free
) pour voir qu'elle est mise en œuvre. EssentiellementFree
appelsDestroy
siSelf
n'est pas nul.Comme le la documentation dit,
"It should not be necessary to call FreeOnRelease directly."
Free
/Release
.+1, à cause de la parole de prudence à propos de la variable globale.
J'ai utilisé Form2 comme un exemple, je donne toujours des formes/composants des noms significatifs tels que frmMain, frmAbout, cmdOK, cmdCancel etc. Il semble d'après quelques commentaires FreeOnRelease est préférable de l'éviter, et Libre, doit être le chemin à parcourir.
La question n'est pas que
Form2
est un non-nom descriptif. Le problème est que vous ne devez pas utiliser le globalvar Form2: TForm2
variable dans la section de l'interface deUnit2
si vous ne letry ShowModal finally Free
chose. Au lieu de cela, vous devez utiliser un variable dans un tel cas. Vous pouvez lui donner un nomForm2
si vous le souhaitez.ok, je comprends maintenant, grâce Andreas, il est plus logique de faire cela.
OriginalL'auteur Cosmin Prund
Je n'ai jamais entendu parler de
FreeOnRelease
avant. Une rapide recherche sur Google s'est jusqu'à la raison. À partir de la documentation officielle:Comme pour
Free
vsDestroy
,Free
est une fonction de sécurité. C'est essentiellement mis en œuvre commeif self <> nil then self.Destroy;
, et il a été créé pour les constructeurs et destructeurs sûr à utiliser. Voici l'idée de base:Si vous êtes à la construction de l'objet et une exception non gérée s'est soulevée, le destructeur est appelé. Si votre objet contient d'autres objets, ils peuvent ou peuvent ne pas avoir encore été créé au moment où l'erreur s'est produite, de sorte que vous ne pouvez pas simplement essayer d'appeler
Destroy
sur chacun d'eux. Mais vous avez besoin d'un moyen de faire en sorte que ceux qui ont été créés ne se détruit.Depuis Delphi des zéros de l'espace d'adresse d'un objet avant d'appeler le constructeur, ce qui n'a pas encore été créé, il est garanti à être néant à ce point. Donc on peut dire
if FSubObject <> nil then FSubObject.Destroy
encore et encore pour tous les sous-objets, (et si vous oubliez que vous allez obtenir des violations d'accès, ou vous pouvez utiliser laFree
méthode, qui le fait pour vous. (Ce qui est une énorme amélioration par rapport à C++, où l'espace de la mémoire est pas remis à zéro avant que le constructeur est appelé, ce qui vous oblige à l'emballage de tous vos sous-objets dans des pointeurs intelligents et de l'utilisation RAII pour maintenir l'exception de sécurité!)Il est utile dans d'autres lieux, et il n'y a vraiment aucune raison de ne pas l'utiliser. Je n'ai jamais remarqué que
Free
impose les performances mesurables de la peine, et il améliore la sécurité de votre code, c'est donc une bonne idée de l'utiliser dans tous les cas.Après avoir dit que, lorsque vous traitez avec des formes spécifiquement, il y a une variable supplémentaire facteur dans l'équation: le message de Windows file d'attente. Vous ne savez pas si il y a encore des messages en attente pour le formulaire, vous êtes sur le point d'gratuit, il n'est pas toujours sûr d'appeler
Free
sur un formulaire. Pour cela, il y a laRelease
méthode. Il envoie un message à la file d'attente qui provoque la forme pour se libérer une fois qu'il a pas plus de messages à traiter, il est donc généralement la meilleure façon de libérer un formulaire, vous n'avez plus besoin.OriginalL'auteur Mason Wheeler
La forme canonique est:
Ne jamais appeler
Destroy
, toujours faire appel àFree
à la place.FreeOnRelease
est un total de red herring. Parfois, si il y en file d'attente des messages destinés à votre forme ou de ses enfants, alors vous pourriez choisir d'appelRelease
bien souvent, c'est un indicateur de problèmes de conception.Ma réponse est le plus concis et précis. Les autres réponses apportées à mes yeux écarquillés, mais je suis un enfant de la fois et ne peut pas se concentrer sur de grandes quantités de texte! 😉
toujours utile complément d'info.
Il y a un certain nombre d'imaginer des circonstances dans lesquelles la Libération est parfaitement raisonnable, la plus notable étant la destruction d'un Formulaire à partir de l'intérieur de lui-même. Mais c'est sûr qu'il est sage de l'étude de la nécessité de la Libération.
+1 pour NGLN commentaire. Vous pouvez ne jamais appeler
Free
de l'intérieur de cette forme (par exemple un clic sur un bouton); que, dans une violation d'accès secondes de passe. Mais si vous avez une situation où vous voulez détruire un formulaire qui vous êtes, à vous appelRelease
, et il sera libéré quand il est sécuritaire de le faire. Puisque personne ne veut jamais publier un formulaire de la vertu eux-mêmes - la forme canonique est la meilleure.OriginalL'auteur David Heffernan
Les expressions idiomatiques est
ou, à moins que vous détestez le
with
construire,Vous devriez ne jamais appeler
Destroy
, selon la documentation. En fait,Free
est exactement équivalente àif Self <> nil then Destroy;
. Qui est, il est " sûr " de la version deDestroy
. Il ne plante pas totalement si le pointeur se trouve êtrenil
. [Pour tester cela, ajouter un champ privéFBitmap: TBitmap
à votre classe de formulaire, puis OnCreate (par exemple), essayez deFBitmap.Free
vsFBitmap.Destroy
.]Si vous créez le formulaire à l'aide de l'approche ci-dessus,
Free
est parfaitement sûr, à moins que vous faire des choses étranges dans la classe de formulaire.Toutefois, si vous utilisez
CreateForm(TForm2, Form2)
pour créer la forme et le magasin de la forme de l'objet dans le global variable d'instanceForm2
et vous n'avez pas le libérer immédiatement [par exemple, si vous voulez que la fenêtre de rester à côté de la principale forme dans un non-modale de quelques minutes], vous devriez probablement utiliserRelease
au lieu deFree
. De la documentation,FreeOnRelease
a rien de particulier à faire avec les formes. À partir de la documentation:OriginalL'auteur Andreas Rejbrand
l'autre façon est de passage caFree à l'Action de formonclose
OriginalL'auteur dawood karimy