Delphi komponensek dinamikus létrehozása (futás közben)

Leggyakrabban a Delphi programozásakor nem kell dinamikusan létrehoznia egy összetevőt. Ha eldob egy összetevőt egy űrlapon, a Delphi automatikusan kezeli az összetevő létrehozását az űrlap létrehozásakor. Ez a cikk az összetevők futásidejű programozási létrehozásának helyes módjáról szól.

Dinamikus alkotóelemek létrehozása

Az összetevők dinamikus létrehozására kétféle módja van. Az egyik módszer az, ha az űrlapot (vagy más TComponent-et) az új összetevő tulajdonosává teszik. Ez az a gyakorlat, amikor összetett alkatrészeket építenek, ahol egy vizuális tároló létrehozza és birtokolja az alkotóelemeket. Ezzel biztosítva lesz, hogy az újonnan létrehozott összetevő megsemmisüljön, ha a tulajdonos összetevő megsemmisül.

Egy osztálypéldány (objektum) létrehozásához hívja meg a "Létrehozás" metódust. A konstruktor létrehozása a osztály módszer, szemben a Delphi programozás során gyakorlatilag minden más módszerrel, amelyek objektum módszerek.

Például a TComponent a következőképpen deklarálja a Létrehozást:

instagram viewer

kivitelező létrehozása (tulajdonos: TComponent); virtuális;

Dinamikus létrehozás a tulajdonosokkal
Íme egy példa a dinamikus létrehozásra, ahol Maga egy TComponent vagy TComponent leszármazott (például egy TForm példánya):

TTimerrel. Létrehozás (Saját) csinálás
kezdődik
Intervallum: = 1000;
Engedélyezve: = Hamis;
OnTimer: = MyTimerEventHandler;
végén;

Dinamikus létrehozás egy explicit hívásmentes felhívással
Az összetevő létrehozásának második módja a használata nulla mint tulajdonos. Vegye figyelembe, hogy ha ezt megteszi, akkor kifejezetten fel kell szabadítania a létrehozott objektumot, amint már nincs rá szüksége (vagy előállít egy memória szivárgás). Íme egy példa a nulla tulajdonosként történő használatára:

TT táblával. Létrehozás (nulla) do
próbáld ki
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Nyisd ki;
szerkesztése;
FieldByName ('Foglalt'). AsBoolean: = True;
Hozzászólás;
végül
Ingyenes;
végén;

Dinamikus létrehozás és objektumhivatkozások
A két előző példát tovább lehet fejleszteni, ha a Létrehozás hívásának eredményét a metódushoz tartozó lokális változóhoz vagy az osztályhoz tartozik. Ez gyakran kívánatos, ha a összetevő később kell használni, vagy amikor hatókör Kerülni kell a "With" blokkok által esetlegesen okozott problémákat. Íme egy felülről írt TTimer létrehozási kód, egy mezőváltozó segítségével hivatkozva a megismételt TTimer objektumra:

Időzítő: = Időzítő. Létrehozás (Ön);
az FTimerrel
kezdődik
Intervallum: = 1000;
Engedélyezve: = Hamis;
OnTimer: = MyInternalTimerEventHandler;
végén;

Ebben a példában az "FTimer" az űrlap vagy a vizuális tároló (vagy bármilyen "én") egy privát mezőváltozója. Az FTimer változó elérésekor az osztályba tartozó módszerekből nagyon jó ötlet, hogy használat előtt ellenőrizze, hogy a referencia érvényes-e. Ezt a Delphi hozzárendelt funkcióval végezzük:

ha hozzárendelt (FTimer), akkor FTimer. Engedélyezve: = Igaz;

Dinamikus létrehozás és objektumhivatkozások tulajdonosok nélkül
Ennek egyik változata az, ha az összetevőt tulajdonos nélkül hozza létre, de megőrzi a referenciát a későbbi megsemmisítéshez. A TTimer építési kódja így néz ki:

Időzítő: = Időzítő. Létrehozás (nulla);
az FTimerrel
kezdődik
...
végén;

És a pusztító kód (feltehetően az űrlap pusztítójában) így néz ki:

FTimer. Ingyenes;
FTimer: = nulla;
(*
Vagy használja a FreeAndNil (FTimer) eljárást, amely felszabadítja az objektum referenciát, és a referencia helyébe nullát lép.
*)

Az objektumok referenciaértékének nullra állítása kritikus az objektumok felszabadításakor. A Free hívás először ellenőrzi, hogy az objektumhivatkozás nulla vagy sem, és ha nem, akkor az objektumpusztítót hívja meg.

Dinamikus létrehozás és helyi objektumhivatkozások tulajdonosok nélkül

Íme a felülről elérhető TTable létrehozási kód, egy helyi változó segítségével hivatkozva a megvalósított TTable objektumra:

localTable: = TT asztal. Létrehozás (nulla);
próbáld ki
a localTable segítségével
kezdődik
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
végén;
...
// Később, ha kifejezetten meg akarjuk határozni a hatókört:
localTable. Nyisd ki;
localTable. szerkesztése;
localTable. FieldByName ('Foglalt'). AsBoolean: = True;
localTable. Hozzászólás;
végül
localTable. Ingyenes;
localTable: = nulla;
végén;

A fenti példában a "localTable" a helyi változó ugyanazzal a módszerrel deklarálva, amely tartalmazza ezt a kódot. Vegye figyelembe, hogy bármilyen objektum felszabadítása után általában nagyon jó ötlet nullára állítani a hivatkozást.

A figyelmeztetés szava

FONTOS: Ne keverje össze a Free hívást az érvényes tulajdonos átadásával a kivitelezővel. Az összes korábbi technika működni fog és érvényes, de a következőknek meg kell felelniük soha ne forduljon elő a kódjában:

TT táblával. Készíts (ön) csinálj
próbáld ki
...
végül
Ingyenes;
végén;

A fenti kódpélda szükségtelen teljesítményleírásokat vezet be, kissé befolyásolja a memóriát, és potenciálisan nehéz hibákat találni. Megtudja miért.

Megjegyzés: Ha a dinamikusan létrehozott összetevőnek van tulajdonosa (a létrehozó konstruktor AOwner paramétere meghatározza), akkor a tulajdonos felelős az összetevő megsemmisítéséért. Ellenkező esetben kifejezetten ingyenesnek kell hívnia a Free-et, amikor már nincs szüksége az összetevőre.

A cikk eredetileg: Mark Miller

Egy tesztprogramot hoztak létre a Delphiben, amely időnként 1000 komponens dinamikus létrehozását idézi elő, változó kezdeti komponensszámmal. A tesztprogram az oldal alján jelenik meg. A táblázat a tesztprogram eredményeinek sorozatát mutatja, összehasonlítva az összetevők létrehozásához szükséges időt mind a tulajdonosokkal, mind a nélkül. Vegye figyelembe, hogy ez csak a találat egy része. Hasonló teljesítménykésleltetés várható az alkatrészek megsemmisítésekor. Az összetevők dinamikus létrehozásának ideje a tulajdonosokkal 1200% és 107960% között lassabb, mint a létrehozáshoz alkatrészek tulajdonosok nélkül, az űrlapon lévő elemek számától és az adott alkotóelemtől függően létrehozva.

A tesztprogram

Figyelem: Ez a tesztprogram nem követi nyomon és nem menti fel a komponenseket, amelyeket tulajdonosok nélkül hoztak létre. Ha nem követi nyomon és felszabadítja ezeket az összetevőket, akkor a dinamikus létrehozási kódhoz mért idő pontosabban tükrözi az összetevő dinamikus létrehozásának valós idejét.

Töltse le a forráskódot

Figyelem!

Ha egy Delphi komponenst dinamikusan el akar készíteni, és valamikor később kifejezetten fel szeretné szabadítani, akkor mindig nullát adja meg a tulajdonosnak. Ennek elmulasztása szükségtelen kockázatot, valamint teljesítmény- és kódkarbantartási problémákat okozhat. További információkért olvassa el a "Figyelem a Delphi-komponensek dinamikusan pillanatnyi elindításáért" cikket ...

instagram story viewer