2009-01-23 8 views

Répondre

35

Le composant propriétaire est censé gérer tous ses composants. Les composants possédés sont détruits automatiquement lorsque le propriétaire est détruit. Cela aide le développeur qui ne fait que glisser des composants de la palette d'outils, les dépose sur le formulaire et raccorde simplement les événements pour effectuer son travail sans se préoccuper de la gestion de la durée de vie des composants.

Le formulaire est le propriétaire de tous les composants déposés. L'objet Application est le propriétaire du formulaire. Lorsque l'application est fermée, l'objet Application est détruit, ce qui à son tour détruit les formulaires et tous les composants.

Mais le propriétaire n'est pas vraiment nécessaire lors de la création d'un composant. Si vous passez Nil au paramètre, le composant sera créé sans propriétaire et dans ce cas, il sera de votre responsabilité de gérer la durée de vie du composant.

+0

Bonne réponse. Donc, si je voulais gérer moi-même la vie, comment pourrais-je m'assurer qu'un objet est détruit quand j'en ai fini avec lui? – Dave

+1

@prapin: Une légère correction est nécessaire: L'objet Application est uniquement propriétaire d'un formulaire si le formulaire a été créé avec Application.CreateForm() ou lorsque Application a été transmise à Create as AOwner. Un formulaire peut être détenu par un autre formulaire, ou tout autre composant d'ailleurs. – mghie

+0

@Dave: Les questions SO suivantes traitent de la propriété de l'objet: http://stackoverflow.com/questions/398137/what-is-the-best-way-to-do-nested-try-and-finally-statement-in- delphi # 399860, http://stackoverflow.com/questions/415958/how-to-automatically-free-classes-objects#415990 – mghie

9

Tous les descendants TComponent requièrent Owner, il est défini dans le constructeur TComponent. Le composant Owner est responsable de la destruction de tous les composants appartenant à Owned.

Si vous voulez contrôler la durée de vie, vous pouvez passer nul en paramètre.

3

Juste pour ajouter quelques informations supplémentaires.

Chaque contrôle a également un parent. (Un TWinControl). Lorsque le propriétaire prend soin de la vie, le parent prend soin de montrer l'objet.

Par exemple une forme a un panneau et le panneau a un bouton. Dans ce cas, le formulaire possède le panneau et le bouton. Mais le formulaire est le parent du panneau et le panneau est le parent du bouton.

+1

Oui, mais tous les composants (TComponent) ne sont pas des contrôles (TControl). TControl descend de TComponent. Un composant qui n'est pas un contrôle n'a pas de parent. –

+0

Notez également que si vous détruisez un parent, les enfants seront également détruits, même s'ils n'appartiennent pas au parent. –

3

Il y a aussi quelque chose d'autre à connaître. J'ai utilisé plus de quelques composants tiers qui comptent sur un composant Propriétaire étant passé dans le constructeur créer, et si vous passez dans Nil lancera une exception/AV.

Le résultat net est que ces composants fonctionneront correctement lorsque vous utilisez le visuellement dans l'EDI mais que des problèmes surviennent lors de leur création au moment de l'exécution.

La cause de ces problèmes est, en un sens, mauvaise conception. Rien dans l'état des règles vous ne pouvez/ne devez pas passer dans NIL comme paramètre aOwner.

1

L'objet ne doit pas EXIGER un tComponent doit être passé en tant que AOwner. Vous pouvez facilement passer à zéro et gérer vous-même la destruction. Le plus souvent, j'ai tendance à utiliser cette technique pour des routines localisées où le composant utilisé ne sera pas utilisé en dehors de la méthode actuelle.par exemple:

Procedure TForm1.Foo; 
var 
    XmlDoc : tXmlDocument; 
begin 
    XmlDoc := tXmlDocument.Create(nil); 
    try 
    // do processing of the XMLDoc here 
    finally 
    FreeAndNil(XmlDoc); 
    end; 
end; 
+2

'TXMLDocument' est un cas particulier. Lorsque vous passez un propriétaire 'nil' à son constructeur, l'objet agit comme une interface comptée par référence, pas un composant! En tant que tel, vous devez ** affecter ** l'objet à une variable d'interface 'IXMLDocument' afin de maintenir correctement ce nombre de références. Ce comportement est documenté dans l'aide. Puisque vous devez utiliser 'IXMLDocument' dans ce cas, il vaut mieux utiliser' NewXMLDocument() 'et les fonctions associées au lieu d'instancier' TXMLDocument' manuellement. –

0

Vous shoudl utiliser ceci pour deux raisons: - le mécanisme de propriété se distingue également comme une sorte de système de collecte des ordures - le mécanisme de propriété est importante dans le processus de sérialisation Delphi (Stream.ReadComponent/WriteComponent etc).

0

Un paramètre Propriétaire n'est nécessaire que pour les descendants TComponent, car il s'agit d'un paramètre du constructeur TComponent. Tous les composants accessibles au moment de la conception pour la suppression des classes TForm, TFrame et TDataModule sont TComponent descendants (qui inclut TXMLDocument).