Τις περισσότερες φορές όταν προγραμματίζετε στους Δελφούς δεν χρειάζεται να δημιουργήσετε δυναμικά ένα στοιχείο. Εάν αποθέσετε ένα στοιχείο σε μια φόρμα, η Delphi χειρίζεται αυτόματα τη δημιουργία συστατικών στοιχείων όταν δημιουργηθεί η φόρμα. Αυτό το άρθρο θα καλύψει τον σωστό τρόπο δημιουργίας προγραμματιστικών στοιχείων κατά την εκτέλεση.
Δημιουργία δυναμικών στοιχείων
Υπάρχουν δύο τρόποι για τη δυναμική δημιουργία στοιχείων. Ένας τρόπος είναι να κάνετε μια φόρμα (ή κάποια άλλη TComponent) τον ιδιοκτήτη του νέου στοιχείου. Αυτή είναι μια κοινή πρακτική κατά την κατασκευή σύνθετων εξαρτημάτων όπου ένας οπτικός περιέκτης δημιουργεί και κατέχει τις επιμέρους συνιστώσες. Με τον τρόπο αυτό θα διασφαλιστεί ότι το συστατικό που δημιουργήθηκε πρόσφατα θα καταστραφεί όταν καταστραφεί το ιδιοκτήτη.
Για να δημιουργήσετε μια παρουσία (αντικείμενο) μιας κλάσης, καλείτε τη μέθοδο "Δημιουργία". Ο δημιουργός δημιουργίας είναι a class μέθοδο, σε αντίθεση με σχεδόν όλες τις άλλες μεθόδους που θα συναντήσετε στον προγραμματισμό των Δελφών, οι οποίες είναι μέθοδοι αντικειμένων.
Για παράδειγμα, το TComponent δηλώνει τον Δημιουργό κατασκευαστή ως εξής:
Κατασκευαστής Δημιουργία (AOwner: TComponent); εικονικός;
Δυναμική Δημιουργία με Ιδιοκτήτες
Ακολουθεί ένα παράδειγμα δυναμικής δημιουργίας, όπου Εαυτός είναι ένας απόγονος TComponent ή TComponent (π.χ. μια περίπτωση ενός TForm):
με το TTimer. Δημιουργήστε (Αυτο) κάνετε
ξεκινήσει
Διάστημα: = 1000;
Ενεργοποίηση: = Λάθος;
OnTimer: = MyTimerEventHandler;
τέλος;
Δυναμική δημιουργία με μια ρητή κλήση προς δωρεάν
Ο δεύτερος τρόπος για να δημιουργήσετε ένα στοιχείο είναι να χρησιμοποιήσετε μηδέν ως ιδιοκτήτης. Σημειώστε ότι εάν το κάνετε αυτό, πρέπει επίσης να απελευθερώσετε ρητά το αντικείμενο που δημιουργείτε μόλις δεν το χρειάζεστε (ή θα παράγετε ένα έλλειψη μνήμης). Ακολουθεί ένα παράδειγμα χρήσης του μηδενός ως ιδιοκτήτη:
με TTable. Δημιουργία (μηδέν) κάνουμε
δοκιμάστε
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Ανοιξε;
Επεξεργασία;
FieldByName ('Απασχολημένος') AsBoolean: = True;
Θέση;
τελικά
Ελεύθερος;
τέλος;
Δυναμική δημιουργία και αναφορές αντικειμένων
Είναι δυνατή η ενίσχυση των δύο προηγούμενων παραδειγμάτων, αναθέτοντας το αποτέλεσμα της δημιουργίας κλήσης σε μια μεταβλητή τοπική στη μέθοδο ή που ανήκει στην κλάση. Αυτό συχνά είναι επιθυμητό όταν οι αναφορές στο συστατικό πρέπει να χρησιμοποιηθούν αργότερα ή πότε το πεδίο εφαρμογής τα προβλήματα που ενδεχομένως προκαλούνται από μπλοκ "με" πρέπει να αποφευχθούν. Εδώ είναι ο κώδικας δημιουργίας TTimer από πάνω, χρησιμοποιώντας μια μεταβλητή πεδίου ως αναφορά στο instantiated TTimer αντικείμενο:
FTimer: = TTimer. Δημιουργία (Self);
με το FTimer
ξεκινήσει
Διάστημα: = 1000;
Ενεργοποίηση: = Λάθος;
OnTimer: = MyInternalTimerEventHandler;
τέλος;
Σε αυτό το παράδειγμα το "FTimer" είναι μια ιδιωτική μεταβλητή πεδίου της μορφής ή του οπτικού περιέκτη (ή οτιδήποτε είναι "Self"). Κατά την πρόσβαση στη μεταβλητή FTimer από μεθόδους αυτής της κλάσης, είναι πολύ καλή ιδέα να ελέγξετε αν η αναφορά είναι έγκυρη πριν τη χρησιμοποιήσετε. Αυτό γίνεται με τη λειτουργία Assigned του Delphi:
αν έχει εκχωρηθεί (FTimer) τότε FTimer. Ενεργοποίηση: = Αλήθεια.
Δυναμική Δημιουργία και Παραπομπές Αντικειμένων χωρίς Ιδιοκτήτες
Μια παραλλαγή σε αυτό είναι να δημιουργήσετε το στοιχείο χωρίς ιδιοκτήτη, αλλά να διατηρήσετε την αναφορά για μεταγενέστερη καταστροφή. Ο κώδικας κατασκευής του TTimer θα έμοιαζε έτσι:
FTimer: = TTimer. Δημιουργία (μηδέν);
με το FTimer
ξεκινήσει
...
τέλος;
Και ο κώδικας καταστροφής (πιθανώς στο καταστροφικό της φόρμας) θα φαινόταν έτσι:
FTimer. Ελεύθερος;
FTimer: = μηδέν.
(*
Ή χρησιμοποιήστε τη διαδικασία FreeAndNil (FTimer), η οποία απελευθερώνει μια αναφορά αντικειμένου και αντικαθιστά την αναφορά με μηδέν.
*)
Η ρύθμιση της αναφοράς του αντικειμένου στο μηδέν είναι κρίσιμη όταν απελευθερώνετε αντικείμενα. Η κλήση στο Free πρώτα ελέγχει αν η αναφορά αντικειμένου είναι μηδενική ή όχι, και αν δεν είναι, καλεί τον destructor του αντικειμένου Destroy.
Δυναμική Δημιουργία και Τοπικές Αναφορές Αντικειμένων χωρίς Ιδιοκτήτες
Εδώ είναι ο κώδικας δημιουργίας TTable από τα παραπάνω, χρησιμοποιώντας μια τοπική μεταβλητή ως αναφορά στο instantiated TTable αντικείμενο:
localTable: = TTable. Δημιουργία (μηδέν);
δοκιμάστε
με το localTable
ξεκινήσει
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
τέλος;
...
// Αργότερα, αν θέλουμε να καθορίσουμε ρητά το πεδίο εφαρμογής:
localTable. Ανοιξε;
localTable. Επεξεργασία;
localTable. FieldByName ('Απασχολημένος') AsBoolean: = True;
localTable. Θέση;
τελικά
localTable. Ελεύθερος;
localTable: = μηδέν.
τέλος;
Στο παραπάνω παράδειγμα, το "localTable" είναι a τοπική μεταβλητή δηλωθεί με την ίδια μέθοδο που περιέχει αυτόν τον κώδικα. Λάβετε υπόψη ότι μετά την απελευθέρωση οποιουδήποτε αντικειμένου, γενικά είναι πολύ καλή ιδέα να ορίσετε την αναφορά σε μηδέν.
Λόγο προειδοποίησης
ΣΗΜΑΝΤΙΚΟ: Μην ανακατεύετε μια κλήση στο Free με την παράδοση ενός έγκυρου κατόχου στον κατασκευαστή. Όλες οι προηγούμενες τεχνικές θα λειτουργήσουν και θα είναι έγκυρες, αλλά θα πρέπει να ακολουθήσουν ποτέ δεν εμφανίζονται στον κώδικα σας:
με TTable. Δημιουργήστε (αυτο) κάνετε
δοκιμάστε
...
τελικά
Ελεύθερος;
τέλος;
Το παραπάνω παράδειγμα κώδικα εισάγει περιττές επιτυχίες απόδοσης, επιδρά ελαφρώς στη μνήμη και έχει τη δυνατότητα να εισαγάγει δύσκολα τα σφάλματα. Μάθετε γιατί.
Σημείωση: Εάν ένα δυναμικά δημιουργημένο στοιχείο έχει έναν κάτοχο (ο οποίος καθορίζεται από την παράμετρο AOwner του κατασκευαστή δημιουργίας), τότε αυτός ο κάτοχος είναι υπεύθυνος για την καταστροφή του στοιχείου. Διαφορετικά, πρέπει να καλέσετε ρητά το Free όταν δεν χρειάζεστε πλέον το στοιχείο.
Άρθρο που αρχικά είχε συνταχθεί από την Mark Miller
Ένα πρόγραμμα δοκιμών δημιουργήθηκε στους Δελφούς για να δημιουργήσει δυναμικά τη δημιουργία 1000 συστατικών με διαφορετικές αρχικές συνιστώσες. Το δοκιμαστικό πρόγραμμα εμφανίζεται στο κάτω μέρος αυτής της σελίδας. Το διάγραμμα δείχνει ένα σύνολο αποτελεσμάτων από το πρόγραμμα δοκιμών, συγκρίνοντας το χρόνο που απαιτείται για τη δημιουργία στοιχείων τόσο με τους ιδιοκτήτες όσο και χωρίς. Σημειώστε ότι αυτό είναι μόνο ένα μέρος του χτυπήματος. Μια παρόμοια καθυστέρηση απόδοσης μπορεί να αναμένεται όταν καταστρέφονται εξαρτήματα. Ο χρόνος για τη δυναμική δημιουργία στοιχείων με τους ιδιοκτήτες είναι 1200% έως 107960% πιο αργός από αυτόν που δημιουργήσατε εξαρτήματα χωρίς ιδιοκτήτες, ανάλογα με τον αριθμό των στοιχείων στη φόρμα και το στοιχείο που είναι δημιουργήθηκε.
Το πρόγραμμα δοκιμών
Προειδοποίηση: Αυτό το πρόγραμμα δοκιμής δεν παρακολουθεί και δωρεάν συστατικά που δημιουργούνται χωρίς ιδιοκτήτες. Με τη μη παρακολούθηση και απελευθέρωση αυτών των στοιχείων, οι χρόνοι που μετρούνται για τον κώδικα δυναμικής δημιουργίας αντικατοπτρίζουν ακριβέστερα τον πραγματικό χρόνο για τη δυναμική δημιουργία ενός στοιχείου.
Λήψη πηγαίου κώδικα
Προειδοποίηση!
Αν θέλετε να δημιουργήσετε μια δυναμική παράσταση ενός στοιχείου Delphi και να τον απελευθερώσετε κάποια στιγμή αργότερα, πάντα να περάσετε ως κανένας ιδιοκτήτης. Εάν δεν το κάνετε, μπορεί να δημιουργηθεί περιττός κίνδυνος, καθώς και προβλήματα επιδόσεων και συντήρησης κώδικα. Διαβάστε το άρθρο "Μια προειδοποίηση σχετικά με τα δυναμικά συστατικά στοιχεία των Δελφών" για να μάθετε περισσότερα ...