Cel mai adesea atunci când programați în Delphi nu este necesar să creați dinamic o componentă. Dacă renunțați la o componentă pe un formular, Delphi gestionează automat crearea componentelor atunci când este creat formularul. Acest articol va acoperi modul corect de a crea programatic componente în timpul rulării.
Crearea componentelor dinamice
Există două moduri de a crea în mod dinamic componente. Un mod este de a face un formular (sau un alt TComponent) proprietarul noii componente. Aceasta este o practică obișnuită atunci când construiți componente compuse în care un container vizual creează și deține subcomponentele. Făcând acest lucru, se va asigura că componenta recent creată este distrusă atunci când componenta deținută este distrusă.
Pentru a crea o instanță (obiect) a unei clase, apelați la metoda „Creare”. Creatorul constructor este un metoda clasei, spre deosebire de aproape toate celelalte metode pe care le veți întâlni în programarea Delphi, care sunt metode obiect.
De exemplu, TComponent declară constructorul Create astfel:
constructor Creare (AOwner: TComponent); virtual;
Creație dinamică cu proprietarii
Iată un exemplu de creație dinamică, unde De sine este un descendent TComponent sau TComponent (de exemplu, o instanță a unui TForm):
cu TTimer. Create (Self) do
începe
Interval: = 1000;
Activat: = Fals;
OnTimer: = MyTimerEventHandler;
Sfârșit;
Creare dinamică cu un apel explicit la liber
Al doilea mod de a crea o componentă este de a utiliza zero în calitate de proprietar. Rețineți că, dacă faceți acest lucru, de asemenea, trebuie să eliberați explicit obiectul pe care îl creați imediat ce nu mai aveți nevoie de el (sau veți produce o pierdere de memorie). Iată un exemplu de utilizare a nil ca proprietar:
cu TTable. Create (nil) do
încerca
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Deschis;
Editați | ×;
FieldByName („Ocupat”). AsBoolean: = True;
Post;
in cele din urma
Liber;
Sfârșit;
Creare dinamică și referințe de obiecte
Este posibil să îmbunătățiți cele două exemple anterioare, alocând rezultatul apelului Creare unei variabile locale metodei sau aparținând clasei. Acest lucru este deseori de dorit atunci când se fac referiri la component trebuie utilizate mai târziu sau când de definire a domeniului problemele potențial cauzate de blocurile „cu” trebuie evitate. Iată codul de creare TTimer de mai sus, folosind o variabilă de câmp ca referință la obiectul TTimer inițiat:
FTimer: = TTimer. Creați (Sinele);
cu FTimer do
începe
Interval: = 1000;
Activat: = Fals;
OnTimer: = MyInternalTimerEventHandler;
Sfârșit;
În acest exemplu, „FTimer” este o variabilă de câmp privat a formei sau a containerului vizual (sau orice este „Sinele”). Când accesați variabila FTimer din metodele din această clasă, este foarte bună să verificați pentru a vedea dacă referința este valabilă înainte de a o utiliza. Aceasta se face folosind funcția Delphi Assigned:
dacă Assigned (FTimer), atunci FTimer. Activat: = True;
Creare dinamică și referințe obiect fără proprietari
O variantă este crearea componentei fără proprietar, dar menținerea referinței pentru distrugerea ulterioară. Codul de construcție pentru TTimer ar arăta astfel:
FTimer: = TTimer. Creați (nil);
cu FTimer do
începe
...
Sfârșit;
Iar codul de distrugere (probabil în distrugătorul formei) ar arăta astfel:
FTimer. Liber;
FTimer: = nil;
(*
Sau folosiți procedura FreeAndNil (FTimer), care eliberează o referință de obiect și înlocuiește referința cu nil.
*)
Setarea referinței obiectului la nil este esențială la eliberarea obiectelor. Apelul la Free prime verifică pentru a vedea dacă referința obiectului este nulă sau nu, și dacă nu este, apelează la distrugerea obiectului Distrug.
Creare dinamică și referințe de obiect local fără proprietari
Iată codul de creație TTable de mai sus, folosind o variabilă locală ca referință la obiectul TTable instantiat:
localTable: = TTable. Creați (nil);
încerca
cu localTable do
începe
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Sfârșit;
...
// Ulterior, dacă dorim să specificăm explicit sfera de aplicare:
localTable. Deschis;
localTable. Editați | ×;
localTable. FieldByName („Ocupat”). AsBoolean: = True;
localTable. Post;
in cele din urma
localTable. Liber;
localTable: = nil;
Sfârșit;
În exemplul de mai sus, „localTable” este un variabilă locală declarat în aceeași metodă care conține acest cod. Rețineți că, după eliberarea oricărui obiect, în general, este foarte bună să setați referința la nil.
Un cuvânt de avertizare
IMPORTANT: Nu amestecați un apel către Free cu trecerea unui constructor valid către constructor. Toate tehnicile anterioare vor funcționa și sunt valabile, dar următoarele trebuie nu apare niciodată în codul dvs.:
cu TTable. Create (self) do
încerca
...
in cele din urma
Liber;
Sfârșit;
Exemplul de cod de mai sus introduce rezultate de performanță inutile, afectează ușor memoria și are potențialul de a introduce bug-uri greu de găsit. Află de ce.
Notă: Dacă o componentă creată dinamic are un proprietar (specificat de parametrul AOwner al constructorului de creare), atunci proprietarul este responsabil de distrugerea componentei. În caz contrar, trebuie să apelați explicit la Free când nu mai aveți nevoie de componentă.
Articol scris inițial de Mark Miller
Un program de test a fost creat în Delphi pentru a crea crearea dinamică a 1000 de componente cu număr inițial variabil de componente. Programul de test apare în partea de jos a acestei pagini. Graficul prezintă un set de rezultate din programul de testare, comparând timpul necesar pentru a crea componente atât cu proprietarii, cât și fără. Rețineți că aceasta este doar o porțiune din succes. O întârziere de performanță similară poate fi de așteptat la distrugerea componentelor. Timpul de a crea în mod dinamic componente cu proprietari este de 1200% până la 107960% mai lent decât acela de a crea componente fără proprietari, în funcție de numărul de componente de pe formular și componentă care este creată.
Programul de testare
Avertisment: acest program de testare nu urmărește și eliberează componentele create fără proprietari. Prin faptul că nu urmărește și eliberează aceste componente, timpii măsurați pentru codul de creație dinamică reflectă mai precis timpul real pentru a crea dinamic o componentă.
Descărcați codul sursă
Avertizare!
Dacă doriți să inițiați dinamic o componentă Delphi și să o eliberați explicit cândva mai târziu, treceți întotdeauna nul ca proprietar. Nerespectarea acestui lucru poate introduce riscuri inutile, precum și probleme de performanță și de întreținere a codului. Citiți articolul „Un avertisment privind inițializarea dinamică a componentelor Delphi” pentru a afla mai multe ...