Enamasti ei pea Delphis programmeerimisel komponenti dünaamiliselt looma. Kui jätate komponendi vormile, tegeleb Delphi vormi loomisega komponendi loomisega automaatselt. See artikkel kirjeldab komponentide programmiliseks loomise õiget moodust käitusaja ajal.
Dünaamiline komponentide loomine
Komponentide dünaamiliseks loomiseks on kaks võimalust. Üks võimalus on muuta vorm (või mõni muu TComponent) uue komponendi omanikuks. See on tavaline tava komposiitkomponentide ehitamisel, kus visuaalne konteiner loob ja omab alakomponente. Sellega tagatakse vastloodud komponendi hävimine, kui omandikomponent hävitatakse.
Klassi eksemplari (objekti) loomiseks nimetatakse selle meetodit "Loo". Loo konstruktor on a klassimeetod, erinevalt praktiliselt kõigist muudest meetoditest, mida Delphi programmeerimisel ette näete, mis on objekti meetodid.
Näiteks kuulutab TComponent Loo konstruktor järgmiselt:
konstruktor Loo (Omanik: TComponent); virtuaalne;
Dünaamiline loomine omanikega
Siin on näide dünaamilisest loomisest, kus Ise on TComponent või TComponent järeltulija (nt TFormi näide):
koos TTimeriga. Loo (ise) tee
alustada
Intervall: = 1000;
Lubatud: = Vale;
OnTimer: = MyTimerEventHandler;
lõpp;
Dünaamiline loomine koos selgesõnalise tasuta üleskutsega
Teine viis komponendi loomiseks on kasutamine null kui omanik. Pange tähele, et kui te seda teete, peate ka loodava objekti selgesõnaliselt vabastama niipea, kui te seda enam ei vaja (või siis peate tootma mäluleke). Siin on näide nullist omaniku kasutamise kohta:
koos TTable. Loo (null) tee
proovida
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Avatud;
Redigeeri;
FieldByName ('hõivatud'). AsBoolean: = True;
Postitus;
lõpuks
Tasuta;
lõpp;
Dünaamiline loomine ja objektide viited
Kahte eelnevat näidet on võimalik täiustada, määrates loo kõne tulemuse muutujale, mis on meetodi suhtes kohalik või kuulub klassi. See on sageli soovitav viidete korral komponent tuleb hiljem kasutada või millal ulatuse määramine tuleb vältida probleeme, mis võivad tekkida "koos" -plokkidega. Siin on TTimeri loomiskood ülalt, kasutades väljamuutujat viitena realiseeritud TTimeri objektile:
FTimer: = TTimer. Loo (ise);
koos FTimeriga
alustada
Intervall: = 1000;
Lubatud: = Vale;
OnTimer: = MyInternalTimerEventHandler;
lõpp;
Selles näites on "FTimer" vormi või visuaalse konteineri (või mis iganes "ise") privaatvälumuutuja. Muutujale FTimer selle klassi meetoditest juurdepääsu saamiseks on väga hea mõte enne selle kasutamist kontrollida, kas viide on kehtiv. Selleks kasutatakse Delphi määratud funktsiooni:
kui määratud (FTimer), siis FTimer. Lubatud: = Tõsi;
Dünaamiline loomine ja objektide viited ilma omaniketa
Selle variatsiooniks on luua komponent, millel pole omanikku, kuid säilitada viide hilisemaks hävitamiseks. TTimeri ehituskood näeks välja järgmine:
FTimer: = TTimer. Loo (null);
koos FTimeriga
alustada
...
lõpp;
Ja hävituskood (arvatavasti vormi hävitaja) näeks välja umbes selline:
FTimer. Tasuta;
FTimer: = null;
(*
Või kasutage protseduuri FreeAndNil (FTimer), mis vabastab objekti viite ja asendab viite nulliga.
*)
Objektide viite määramine nullile on objektide vabastamisel kriitiline. Helistamine tasuta kontrollib kõigepealt, kas objekti viide on null või mitte, ja kui seda pole, helistab see objekti hävitajale.
Dünaamiline loomine ja kohalike objektide viited ilma omaniketa
Siin on TTable loomise kood ülalt, kasutades lokaalset muutujat viitena realiseeritud TTable objektile:
localTable: = TTable. Loo (null);
proovida
koos localTable teha
alustada
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
lõpp;
...
// Hiljem, kui tahame ulatust selgesõnaliselt täpsustada:
localTable. Avatud;
localTable. Redigeeri;
localTable. FieldByName ('hõivatud'). AsBoolean: = True;
localTable. Postitus;
lõpuks
localTable. Tasuta;
localTable: = null;
lõpp;
Ülaltoodud näites on "localTable" a kohalik muutuja deklareeritud samal meetodil, mis sisaldab seda koodi. Pange tähele, et pärast mis tahes objekti vabastamist on üldiselt väga hea mõte seada viide nulli.
Hoiatussõna
TÄHTIS: ärge segage tasuta kõnet kehtiva omaniku edastamisega ehitajale. Kõik eelnevad tehnikad toimivad ja kehtivad, kuid järgmised peaksid ei esine kunagi teie koodis:
koos TTable. Loo (ise) tee
proovida
...
lõpuks
Tasuta;
lõpp;
Ülaltoodud koodinäide tutvustab ebavajalikke jõudlustulemusi, mõjutab veidi mälu ja sellel on vigu raske leida. Uurige välja, miks.
Märkus. Kui dünaamiliselt loodud komponendil on omanik (määratud konstruktori loomise parameetriga AOwner), vastutab selle komponendi hävitamise eest see omanik. Vastasel juhul peate selgesõnaliselt helistama tasuta, kui te komponenti enam ei vaja.
Artikkel on algselt kirjutatud Mark Miller
Delfis loodi testprogramm, mis ajastati 1000 komponendi dünaamilist loomist erineva algkomponentide arvuga. Testprogramm kuvatakse selle lehe allosas. Diagramm näitab testiprogrammi tulemuste komplekti, kus võrreldakse komponentide loomiseks kuluvat aega nii omanikega kui ka ilma. Pange tähele, et see on ainult osa kokkulangevusest. Komponentide hävitamisel võib oodata sarnast jõudluse viivitust. Omanikega komponentide dünaamilise loomise aeg on 1200–107960% aeglasem kui loomine komponendid ilma omaniketa, sõltuvalt vormil olevate komponentide arvust ja olevast komponendist loodud.
Testprogramm
Hoiatus: see testimisprogramm ei jälgi ega vabasta komponente, mis on loodud ilma omaniketa. Neid komponente mitte jälgides ja vabastamata kajastavad dünaamilise loomise koodi jaoks mõõdetud ajad komponendi dünaamilise loomise tegelikku aega täpsemalt.
Laadige lähtekood alla
Hoiatus!
Kui soovite Delphi komponenti dünaamiliselt kiirendada ja millalgi selle selgesõnaliselt vabastada, andke omanikule alati null. Selle tegemata jätmine võib tekitada tarbetuid riske, samuti toimivuse ja koodi hooldamise probleeme. Lisateabe saamiseks lugege artiklit "Hoiatus Delphi komponentide dünaamiliselt kiirendamise kohta" ...