Najčešće kada programirate u Delphiju ne morate dinamički stvarati komponentu. Ako ispustite komponentu na obrazac, Delphi automatski obrađuje stvaranje komponente kada se oblik stvori. Ovaj će članak opisati ispravan način programskog stvaranja komponenti tijekom izvođenja.
Stvaranje dinamičke komponente
Postoje dva načina za dinamičko stvaranje komponenata. Jedan od načina je napraviti obrazac (ili neki drugi TComponent) vlasnikom nove komponente. Ovo je uobičajena praksa za izgradnju složenih komponenti gdje vizualni spremnik stvara i posjeduje potkomponente. Time ćete osigurati da se novostvorena komponenta uništi kada se uništi vlasnička komponenta.
Da biste stvorili instancu (objekt) klase, zovete njezinu metodu "Stvori". Konstruktor Stvori je a metoda klase, za razliku od gotovo svih drugih metoda na koje ćete naići u programiranju Delphija, a to su objektne metode.
Na primjer, TComponent izjavljuje konstruktor Create na sljedeći način:
konstruktor Stvori (AOwner: TComponent); virtualan;
Dinamična kreacija s vlasnicima
Evo primjera dinamičkog stvaranja, gdje sam je potomak TComponent ili TComponent (npr., instanca TForma):
s TTimerom. Stvorite (samo) napravite
početi
Interval: = 1000;
Omogućeno: = Lažno;
OnTimer: = MyTimerEventHandler;
kraj;
Dinamična kreacija s eksplicitnim pozivom na besplatno
Drugi način stvaranja komponente je upotreba nula kao vlasnik. Imajte na umu da ako to učinite, morate izričito osloboditi i objekt koji ste stvorili čim vam više nije potreban (ili ćete proizvesti curenje memorije). Evo primjera upotrebe nula kao vlasnika:
s TTableom. Stvoriti (nula) učiniti
probati
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Otvoren;
Uredi;
FieldByName ('zauzeto'). AsBoolean: = Istina;
Post;
konačno
Besplatno;
kraj;
Dinamička referenca stvaranja i stvaranja
Dva prethodna primjera moguće je poboljšati dodjeljivanjem rezultata Stvaranje poziva varijabli koja je lokalna metodi ili pripadanju klasi. To je često poželjno kada se pozivaju na sastavni dio trebate upotrijebiti kasnije ili kada scoping treba izbjegavati probleme koji su potencijalno uzrokovani blokovima "With". Evo gornjeg koda stvaranja TTimera, koristeći varijablu polja kao referencu na trenutačni TTimer objekt:
FTimer: = TTimer. Stvorite (samo);
s FTimer do
početi
Interval: = 1000;
Omogućeno: = Lažno;
OnTimer: = MyInternalTimerEventHandler;
kraj;
U ovom primjeru "FTimer" je varijabla privatnog polja oblika ili vizualnog spremnika (ili što god bilo "Self"). Pri pristupu varijabli FTimer iz metoda iz ove klase, dobra je ideja provjeriti je li referenca valjana prije upotrebe. To se postiže dodijeljenom funkcijom tvrtke Delphi:
ako je dodijeljeno (FTimer), tada FTimer. Omogućeno: = Istina;
Dinamičko stvaranje i reference objekta bez vlasnika
Varijacija u tome je stvaranje komponente bez vlasnika, ali održavanje reference za kasnije uništenje. Građevinski kod TTimera izgledao bi ovako:
FTimer: = TTimer. Stvoriti (nula);
s FTimer do
početi
...
kraj;
A kôd za uništavanje (vjerojatno u destruktoru forme) izgledao bi ovako:
FTimer. Besplatno;
FTimer: = nula;
(*
Ili koristite postupak FreeAndNil (FTimer), koji oslobađa referencu objekta i zamjenjuje referencu nil.
*)
Postavljanje referencije objekta na nulu kritično je prilikom oslobađanja objekata. Poziv na Free najprije provjerava je li referenca objekta nula ili ne, a ako nije, zove se Destructor objekta Destroy.
Dinamičko stvaranje i reference lokalnog objekta bez vlasnika
Evo gornjeg koda stvaranja TTable-a, koristeći lokalnu varijablu kao referencu na trenutačni objekt TTable:
localTable: = TTable. Stvoriti (nula);
probati
s lokalnom tablicom učiniti
početi
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
kraj;
...
// Kasnije, ako želimo eksplicitno odrediti opseg:
localTable. Otvoren;
localTable. Uredi;
localTable. FieldByName ('zauzeto'). AsBoolean: = Istina;
localTable. Post;
konačno
localTable. Besplatno;
localTable: = nula;
kraj;
U gornjem primjeru, "localTable" je a lokalna varijabla deklarisan na isti način koji sadrži ovaj kod. Imajte na umu da je nakon oslobađanja bilo kojeg objekta, generalno dobra ideja postaviti referencu na nulu.
Riječ upozorenja
VAŽNO: Ne miješajte poziv na Free sa davanjem konstruktora valjanom vlasniku. Sve dosadašnje tehnike funkcionirat će i vrijede, ali sljedeće bi trebalo nikad se ne pojavljuju u vašem kodu:
s TTableom. Stvorite (samo) radite
probati
...
konačno
Besplatno;
kraj;
Gore navedeni primjer koda uvodi nepotrebne pogotke performansi, malo utječe na memoriju i može uvesti teško pronalaženje grešaka. Otkrijte zašto.
Napomena: Ako dinamički stvorena komponenta ima vlasnika (određeno parametrom AOwner konstruktora Create), tada je taj vlasnik odgovoran za uništavanje komponente. U suprotnom morate izričito nazvati Besplatno kad komponenta više ne treba.
Članak izvorno napisao Mark Miller
U Delfima je stvoren testni program kako bi se vremenski stvorilo dinamično stvaranje 1000 komponenti s različitim brojem početnih komponenata. Testni program pojavljuje se na dnu ove stranice. Grafikon prikazuje skup rezultata iz testnog programa, uspoređujući vrijeme potrebno za stvaranje komponenata i s vlasnicima i bez njih. Napominjemo da je ovo samo dio učitavanja. Slična odgoda performansi može se očekivati pri uništavanju komponenata. Vrijeme za dinamičko stvaranje komponenti s vlasnicima je 1200% do 107960% sporije nego za kreiranje komponente bez vlasnika, ovisno o broju komponenti u obliku i sastavnici stvorio.
Program testiranja
Upozorenje: Ovaj testni program ne prati i ne uključuje besplatne komponente koje su kreirane bez vlasnika. Ne prateći i oslobađajući ove komponente, vremena izmjerena za dinamički kôd za stvaranje točnije odražavaju stvarno vrijeme za dinamičko stvaranje komponente.
Preuzmite izvorni kod
Upozorenje!
Ako želite dinamički aktivirati Delphi komponentu i izričito je osloboditi nešto kasnije, uvijek unesite nil kao vlasnika. Ako to ne učinite, može se uvesti nepotreban rizik, kao i problemi sa izvedbom i održavanjem koda. Pročitajte članak "Upozorenje o dinamički instantizaciji Delphi komponenti" da biste saznali više ...