Interessant

Componenten dynamisch maken (tijdens runtime)

Componenten dynamisch maken (tijdens runtime)

Meestal hoeft u bij het programmeren in Delphi niet dynamisch een component te maken. Als u een component op een formulier neerzet, verwerkt Delphi de componentcreatie automatisch wanneer het formulier wordt gemaakt. Dit artikel behandelt de juiste manier om programmatisch componenten te maken tijdens runtime.

Creatie van dynamische componenten

Er zijn twee manieren om dynamisch componenten te maken. Een manier is om een ​​formulier (of een andere TComponent) eigenaar te maken van de nieuwe component. Dit is een gebruikelijke praktijk bij het bouwen van samengestelde componenten waarbij een visuele container de subcomponenten maakt en bezit. Als u dit doet, wordt ervoor gezorgd dat de nieuw gemaakte component wordt vernietigd wanneer de eigen component wordt vernietigd.

Als u een instantie (object) van een klasse wilt maken, noemt u de methode 'Maken'. De Create-constructor is een klassemethode, in tegenstelling tot vrijwel alle andere methoden die u tegenkomt in Delphi-programmering, die objectmethoden zijn.

De TComponent verklaart de Create-constructor bijvoorbeeld als volgt:

constructor Maken (AOwner: TComponent); virtual;

Dynamische creatie met eigenaren
Hier is een voorbeeld van dynamische creatie, waar Zelf is een TComponent of TComponent-afstammeling (bijvoorbeeld een instantie van een TForm):

met TTimer.Create (Zelf) doen
beginnen
Interval: = 1000;
Ingeschakeld: = False;
OnTimer: = MyTimerEventHandler;
einde;

Dynamische creatie met een expliciete gratis oproep
De tweede manier om een ​​component te maken is om te gebruiken nul als de eigenaar. Merk op dat als u dit doet, u ook het object dat u maakt expliciet moet bevrijden zodra u het niet langer nodig hebt (of u zult een geheugenlek produceren). Hier is een voorbeeld van het gebruik van nul als de eigenaar:

met TTable.Create (nihil) doen
proberen
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Open;
Bewerk;
FieldByName ('Busy'). AsBoolean: = True;
Post;
Tenslotte
Gratis;
einde;

Dynamische creatie en objectreferenties
Het is mogelijk om de twee voorgaande voorbeelden te verbeteren door het resultaat van de aanroep Create aan een variabele toe te wijzen die lokaal is voor de methode of die tot de klasse behoort. Dit is vaak wenselijk wanneer verwijzingen naar de component later moeten worden gebruikt, of wanneer scopingproblemen die mogelijk worden veroorzaakt door "With" -blokken moeten worden vermeden. Hier is de TTimer-aanmaakcode van hierboven, met behulp van een veldvariabele als referentie naar het instantiërde TTimer-object:

FTimer: = TTimer.Create (Zelf);
met FTimer doen
beginnen
Interval: = 1000;
Ingeschakeld: = False;
OnTimer: = MyInternalTimerEventHandler;
einde;

In dit voorbeeld is "FTimer" een variabele van het privéveld met de vorm of visuele container (of wat "Zelf" ook is). Wanneer u de FTimer-variabele opent vanuit methoden in deze klasse, is het een goed idee om te controleren of de referentie geldig is voordat u deze gebruikt. Dit wordt gedaan met behulp van de toegewezen functie van Delphi:

indien toegewezen (FTimer) dan FTimer.Enabled: = True;

Dynamische creatie en objectreferenties zonder eigenaren
Een variatie hierop is het maken van het onderdeel zonder eigenaar, maar de referentie behouden voor latere vernietiging. De constructiecode voor de TTimer ziet er als volgt uit:

FTimer: = TTimer.Create (nul);
met FTimer doen
beginnen

einde;

En de vernietigingscode (vermoedelijk in de destructor van de vorm) zou er ongeveer zo uitzien:

FTimer.Free;
FTimer: = nul;
(*
Of gebruik de FreeAndNil (FTimer) procedure, die een objectreferentie bevrijdt en de referentie door nul vervangt.
*)

Het instellen van de objectreferentie op nul is cruciaal bij het vrijmaken van objecten. De aanroep naar Free controleert eerst of de objectreferentie nul is of niet, en als dit niet het geval is, wordt de destructor van het object Destroy genoemd.

Dynamische creatie en lokale objectreferenties zonder eigenaren

Hier is de TTable-creatiecode van hierboven, met behulp van een lokale variabele als verwijzing naar het instantiërde TTable-object:

localTable: = TTable.Create (nul);
proberen
met localTable doen
beginnen
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
einde;

// Later, als we het bereik expliciet willen specificeren:
localTable.Open;
localTable.Edit;
localTable.FieldByName ('Busy'). AsBoolean: = True;
localTable.Post;
Tenslotte
localTable.Free;
localTable: = nul;
einde;

In het bovenstaande voorbeeld is "localTable" een lokale variabele die wordt gedeclareerd in dezelfde methode die deze code bevat. Merk op dat na het bevrijden van een object het in het algemeen een goed idee is om de referentie op nul te zetten.

Een waarschuwing

BELANGRIJK: meng een oproep naar Free niet met het doorgeven van een geldige eigenaar aan de constructor. Alle voorgaande technieken werken en zijn geldig, maar het volgende zou moeten kom nooit in uw code voor:

met TTable.Create (zelf) doen
proberen

Tenslotte
Gratis;
einde;

Het bovenstaande codevoorbeeld introduceert onnodige prestaties, beïnvloedt het geheugen enigszins en heeft het potentieel om moeilijk te vinden bugs te introduceren. Erachter te komen waarom.

Opmerking: Als een dynamisch aangemaakte component een eigenaar heeft (gespecificeerd door de parameter AOwner van de constructor Create), dan is die eigenaar verantwoordelijk voor het vernietigen van de component. Anders moet u expliciet Gratis bellen als u het onderdeel niet langer nodig hebt.

Artikel oorspronkelijk geschreven door Mark Miller

Een testprogramma is gemaakt in Delphi om de dynamische creatie van 1000 componenten met variërende initiële aantal componenten te timen. Het testprogramma verschijnt onderaan deze pagina. De grafiek toont een set resultaten van het testprogramma, waarbij de tijd wordt vergeleken die nodig is om componenten te maken, zowel met als zonder eigenaars. Merk op dat dit slechts een deel van de hit is. Een vergelijkbare prestatievertraging kan worden verwacht bij het vernietigen van componenten. De tijd om dynamisch componenten met eigenaren te maken is 1200% tot 107960% langzamer dan die om componenten zonder eigenaars te maken, afhankelijk van het aantal componenten op het formulier en de component die wordt gemaakt.

Het testprogramma

Waarschuwing: dit testprogramma houdt geen componenten bij die gratis zijn gemaakt zonder eigenaren. Door deze componenten niet te volgen en vrij te geven, geven de gemeten tijden voor de dynamische creatiecode een nauwkeuriger beeld van de realtime om een ​​component dynamisch te creëren.

Download broncode

Waarschuwing!

Als u een Delphi-component dynamisch wilt instantiëren en deze ergens later expliciet wilt bevrijden, geef dan altijd nul door als eigenaar. Als u dit niet doet, kan dit onnodige risico's en prestatie- en codeonderhoudsproblemen veroorzaken. Lees het artikel "Een waarschuwing over Delphi-componenten die dynamisch worden instantieerd" voor meer informatie ...


Bekijk de video: Opleiding: SketchUp gevorderd: dynamische componenten (December 2020).