Opprette Delphi-komponenter dynamisk (på kjøretid)

click fraud protection

Oftest når du programmerer i Delphi, trenger du ikke å lage en komponent dynamisk. Hvis du slipper en komponent på et skjema, håndterer Delphi komponentopprettelsen automatisk når skjemaet opprettes. Denne artikkelen vil dekke den riktige måten å programmatisk lage komponenter ved kjøretid.

Oppretting av dynamisk komponent

Det er to måter å dynamisk lage komponenter. En måte er å lage et skjema (eller noen annen TComponent) som eier av den nye komponenten. Dette er en vanlig praksis når du bygger sammensatte komponenter der en visuell beholder oppretter og eier underkomponentene. Dette vil sikre at den nyopprettede komponenten blir ødelagt når den eier komponenten blir ødelagt.

For å opprette en forekomst (objekt) av en klasse, kaller du dens "Create" -metode. Create-konstruktøren er en klassemetode, i motsetning til så godt som alle andre metoder du vil møte i Delphi-programmering, som er objektmetoder.

For eksempel erklærer TComponenten Create constructor som følger:

konstruktør Create (AOwner: TComponent); virtuell;

instagram viewer

Dynamisk skapelse med eiere
Her er et eksempel på dynamisk skapelse, hvor Selv er en TComponent- eller TComponent-etterkommer (f.eks. en forekomst av en TForm):

med TTimer. Create (Self) do
begynne
Intervall: = 1000;
Aktivert: = Falske;
OnTimer: = MyTimerEventHandler;
slutt;

Dynamisk oppretting med en eksplisitt samtale til gratis
Den andre måten å lage en komponent på er å bruke nil som eier. Merk at hvis du gjør dette, må du også eksplisitt frigjøre objektet du oppretter, så snart du ikke lenger trenger det (eller så produserer du et hukommelsestap). Her er et eksempel på bruk av nil som eier:

med TTable. Opprett (null) gjør
prøve
DataBaseName: = 'MyAlias';
Tabellnavn: = 'MyTable';
Åpen;
Redigere;
FieldByName ('Busy'). AsBoolean: = True;
Post;
endelig
Gratis;
slutt;

Dynamisk oppretting og objektreferanser
Det er mulig å forbedre de to foregående eksemplene ved å tilordne resultatet av Opprett samtalen til en variabel lokal til metoden eller tilhørende klassen. Dette er ofte ønskelig når referanser til komponent trenger å bli brukt senere, eller når scoping problemer som potensielt er forårsaket av "With" -blokker, må unngås. Her er TTimer-opprettingskoden ovenfra, og bruker en feltvariabel som referanse til det instantiserte TTimer-objektet:

FTimer: = TTimer. Opprette (Selv);
med FTimer do
begynne
Intervall: = 1000;
Aktivert: = Falske;
OnTimer: = MyInternalTimerEventHandler;
slutt;

I dette eksemplet er "FTimer" en privat feltvariabel av formen eller visuell beholder (eller hva "Selv" er). Når du får tilgang til FTimer-variabelen fra metoder i denne klassen, er det en veldig god idé å sjekke om referansen er gyldig før du bruker den. Dette gjøres ved å bruke Delphis Assigned-funksjon:

hvis tilordnet (FTimer) så FTimer. Aktivert: = Sann;

Dynamisk oppretting og objektreferanser uten eiere
En variant av dette er å lage komponenten uten eier, men opprettholde referansen for senere ødeleggelse. Konstruksjonskoden for TTimer vil se slik ut:

FTimer: = TTimer. Lag (null);
med FTimer do
begynne
...
slutt;

Og ødeleggelseskoden (antagelig i formens ødelegger) ville se noe slik ut:

FTimer. Gratis;
FTimer: = null;
(*
Eller bruk FreeAndNil (FTimer) prosedyre, som frigjør en objektreferanse og erstatter referansen med null.
*)

Å stille objektreferansen til null er avgjørende når du frigjør objekter. Samtalen til gratis sjekker først for å se om objektreferansen er null eller ikke, og hvis den ikke er det, kaller den objektets ødelegger Destroy.

Dynamisk oppretting og lokale objektreferanser uten eiere

Her er TTable-opprettingskoden ovenfra og bruker en lokal variabel som referanse til det instantiserte TTable-objektet:

localTable: = TTable. Lag (null);
prøve
med localTable do
begynne
DataBaseName: = 'MyAlias';
Tabellnavn: = 'MyTable';
slutt;
...
// Senere, hvis vi ønsker å spesifisere omfang:
localTable. Åpen;
localTable. Redigere;
localTable. FieldByName ('Busy'). AsBoolean: = True;
localTable. Post;
endelig
localTable. Gratis;
localTable: = null;
slutt;

I eksemplet over er "localTable" en lokal variabel deklarert på samme metode som inneholder denne koden. Legg merke til at etter generelt å frigjøre ethvert objekt, er det generelt en god idé å angi referansen til null.

Et advarselsord

VIKTIG: Ikke bland en samtale til Free med å gi en gyldig eier til konstruktøren. Alle de tidligere teknikkene vil fungere og er gyldige, men følgende bør forekommer aldri i koden din:

med TTable. Lag (egen) gjøre
prøve
...
endelig
Gratis;
slutt;

Kodeksemplet ovenfor introduserer unødvendige ytelsestreff, påvirker minnet litt og har potensiale til å introdusere vanskelig å finne feil. Finn ut hvorfor.

Merk: Hvis en dynamisk opprettet komponent har en eier (spesifisert av AOwner-parameteren i Create constructor), er den eieren ansvarlig for å ødelegge komponenten. Ellers må du eksplisitt ringe gratis når du ikke lenger trenger komponenten.

Artikkelen opprinnelig skrevet av Mark Miller

Et testprogram ble opprettet i Delphi for å tid til den dynamiske opprettelsen av 1000 komponenter med varierende startkomponenttelling. Testprogrammet vises nederst på denne siden. Diagrammet viser et sett med resultater fra testprogrammet, og sammenligner tiden det tar å lage komponenter både med eiere og uten. Merk at dette bare er en del av treffet. En lignende ytelsesforsinkelse kan forventes når du ødelegger komponenter. Tiden for dynamisk å lage komponenter med eiere er 1200% til 107960% saktere enn den å lage komponenter uten eiere, avhengig av antall komponenter på skjemaet og komponenten som er opprettet.

Testprogrammet

Advarsel: Dette testprogrammet sporer ikke og frigjør komponenter som er opprettet uten eiere. Ved å ikke spore og frigjøre disse komponentene, reflekterer tider målt for den dynamiske opprettingskoden mer nøyaktig sanntid for å dynamisk opprette en komponent.

Last ned kildekoden

Advarsel!

Hvis du ønsker å dynamisere en Delphi-komponent dynamisk og eksplisitt frigjøre den en gang senere, må du alltid gi deg null som eier. Unnlatelse av å gjøre dette kan føre til unødvendig risiko, i tillegg til problemer med ytelse og kode. Les artikkelen "En advarsel om dynamisk innstifting av Delphi-komponenter" for å lære mer ...

instagram story viewer