Dynamiczne tworzenie komponentów Delphi (w czasie wykonywania)

click fraud protection

Najczęściej podczas programowania w Delphi nie musisz dynamicznie tworzyć komponentu. Jeśli upuścisz komponent na formularzu, Delphi automatycznie utworzy komponent po utworzeniu formularza. W tym artykule opisano prawidłowy sposób programowego tworzenia komponentów w czasie wykonywania.

Dynamiczne tworzenie komponentów

Istnieją dwa sposoby dynamicznego tworzenia komponentów. Jednym ze sposobów jest uczynienie formularza (lub innego TC TConent) właścicielem nowego komponentu. Jest to powszechna praktyka podczas budowania komponentów kompozytowych, w których wizualny kontener tworzy i jest właścicielem podskładników. Spowoduje to, że nowo utworzony komponent zostanie zniszczony po zniszczeniu komponentu będącego właścicielem.

Aby utworzyć instancję (obiekt) klasy, wywołujesz jej metodę „Utwórz”. Konstruktor Utwórz to metoda klasowa, w przeciwieństwie do praktycznie wszystkich innych metod, które napotkasz w programowaniu Delphi, które są metodami obiektowymi.

Na przykład TComponent deklaruje konstruktor Create w następujący sposób:

instagram viewer

konstruktor Create (AOwner: TComponent); wirtualny;

Dynamiczne tworzenie z właścicielami
Oto przykład dynamicznego tworzenia, gdzie Samego siebie jest potomkiem TComponent lub TComponent (np. instancja TForm):

z TTimerem. Utwórz (Self) do
zaczynać
Interwał: = 1000;
Włączone: = False;
OnTimer: = MyTimerEventHandler;
koniec;

Dynamiczne tworzenie z wyraźnym wezwaniem do uwolnienia
Drugim sposobem utworzenia komponentu jest użycie zero jako właściciel. Pamiętaj, że jeśli to zrobisz, musisz również jawnie zwolnić obiekt, który utworzysz, gdy tylko go nie będziesz już potrzebować (lub utworzysz wyciek pamięci). Oto przykład użycia zera jako właściciela:

z TTable. Utwórz (zero) do
próbować
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
Otwarty;
Edytować;
FieldByName („Busy”). AsBoolean: = True;
Poczta;
Wreszcie
Darmowy;
koniec;

Tworzenie dynamiczne i odniesienia do obiektów
Możliwe jest ulepszenie dwóch poprzednich przykładów poprzez przypisanie wyniku wywołania Create do zmiennej lokalnej dla metody lub należącej do klasy. Jest to często pożądane, gdy odniesienia do składnik muszą być wykorzystane później lub kiedy zakres należy unikać problemów potencjalnie spowodowanych przez bloki „With”. Oto kod tworzenia TTimer z góry, wykorzystujący zmienną pola jako odwołanie do utworzonego instancji obiektu TTimer:

FTimer: = TTimer. Utwórz (Jaźń);
z FTimer do
zaczynać
Interwał: = 1000;
Włączone: = False;
OnTimer: = MyInternalTimerEventHandler;
koniec;

W tym przykładzie „FTimer” jest zmienną pola prywatnego formy lub kontenera wizualnego (lub cokolwiek „Self”). Podczas uzyskiwania dostępu do zmiennej FTimer z metod w tej klasie, bardzo dobrym pomysłem jest sprawdzenie, czy referencja jest poprawna przed jej użyciem. Odbywa się to za pomocą przypisanej funkcji Delphi:

jeśli przypisany (FTimer), to FTimer. Włączone: = prawda;

Tworzenie dynamiczne i odwołania do obiektów bez właścicieli
Odmianą jest utworzenie komponentu bez właściciela, ale zachowanie odniesienia do późniejszego zniszczenia. Kod konstrukcyjny TTimer wyglądałby następująco:

FTimer: = TTimer. Utwórz (zero);
z FTimer do
zaczynać
...
koniec;

A kod zniszczenia (prawdopodobnie w formie destruktora formy) wyglądałby mniej więcej tak:

FTimer. Darmowy;
FTimer: = zero;
(*
Lub użyj procedury FreeAndNil (FTimer), która zwalnia odwołanie do obiektu i zastępuje odwołanie zerem.
*)

Ustawienie odwołania do obiektu na zero ma krytyczne znaczenie podczas uwalniania obiektów. Wywołanie Free najpierw sprawdza, czy odwołanie do obiektu jest zerowe, a jeśli nie, wywołuje Destroy obiektu Destroy.

Tworzenie dynamiczne i odwołania do obiektów lokalnych bez właścicieli

Oto kod tworzenia TTable z góry, wykorzystujący zmienną lokalną jako odniesienie do instancji obiektu TTable:

localTable: = TTable. Utwórz (zero);
próbować
z localTable do
zaczynać
DataBaseName: = 'MyAlias';
TableName: = 'MyTable';
koniec;
...
// Później, jeśli chcemy jawnie określić zakres:
localTable. Otwarty;
localTable. Edytować;
localTable. FieldByName („Busy”). AsBoolean: = True;
localTable. Poczta;
Wreszcie
localTable. Darmowy;
localTable: = zero;
koniec;

W powyższym przykładzie „localTable” to zmienna lokalna zadeklarowany tą samą metodą zawierającą ten kod. Zauważ, że po zwolnieniu dowolnego obiektu, ogólnie bardzo dobrym pomysłem jest ustawienie odniesienia na zero.

Słowo ostrzeżenia

WAŻNE: Nie mieszaj połączenia z Free z przekazaniem konstruktora ważnego właściciela. Wszystkie poprzednie techniki będą działać i są prawidłowe, ale poniższe powinny nigdy nie występują w twoim kodzie:

z TTable. Utwórz (self) do
próbować
...
Wreszcie
Darmowy;
koniec;

Powyższy przykład kodu wprowadza niepotrzebne spadki wydajności, nieznacznie wpływa na pamięć i może wprowadzać trudne do znalezienia błędy. Dowiedz się dlaczego.

Uwaga: Jeśli dynamicznie utworzony komponent ma właściciela (określonego przez parametr AOwner konstruktora Utwórz), wówczas ten właściciel jest odpowiedzialny za zniszczenie komponentu. W przeciwnym razie musisz jawnie wywołać opcję Wolny, gdy nie potrzebujesz już komponentu.

Artykuł pierwotnie napisany przez Mark Miller

Program testowy został utworzony w Delphi, aby określić czas dynamicznego tworzenia 1000 komponentów przy różnych początkowych liczbach komponentów. Program testowy pojawia się na dole tej strony. Tabela pokazuje zestaw wyników z programu testowego, porównując czas potrzebny do utworzenia komponentów zarówno z właścicielami, jak i bez nich. Pamiętaj, że to tylko część trafienia. Podobnego opóźnienia wydajności można oczekiwać podczas niszczenia komponentów. Czas na dynamiczne tworzenie komponentów z właścicielami jest o 1200% do 107960% wolniejszy niż na tworzenie komponenty bez właścicieli, w zależności od liczby komponentów w formularzu i komponentu Utworzony.

Program testowy

Ostrzeżenie: ten program testowy nie śledzi i nie zwalnia komponentów tworzonych bez właścicieli. Nie śledząc i nie uwalniając tych komponentów, czasy zmierzone dla dynamicznego kodu tworzenia dokładniej odzwierciedlają czas rzeczywisty do dynamicznego tworzenia komponentu.

Pobierz kod źródłowy

Ostrzeżenie!

Jeśli chcesz dynamicznie utworzyć instancję komponentu Delphi i jawnie go zwolnić później, zawsze przekaż zero jako właściciel. Niezastosowanie się do tego może spowodować niepotrzebne ryzyko, a także problemy z wydajnością i konserwacją kodu. Przeczytaj artykuł „Ostrzeżenie o dynamicznym tworzeniu instancji komponentów Delphi”, aby dowiedzieć się więcej ...

instagram story viewer