Autor Téma: System.Generics.Collections.TObjectList.Clear  (Přečteno 409 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5295
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
System.Generics.Collections.TObjectList.Clear
« kdy: 13-12-2019, 17:42:34 »
Citujem z návodu
Citace
TObjectList is a TList with the capability of automatically freeing object entries when they are removed from the list. When a TObjectList is instantiated, an AOwnsObjects parameter specifies whether the list owns the list entries. If the entry is owned, when the entry object is removed from the list, the entry object is freed.
Teraz som po dlhom čase s hrôzou zistil, že po zavolaní Clear objekty sú zničené, ale nie sú nil. Má to tak byť? Mne sa to vôbec nepozdáva.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 1063
  • Karma: 47
    • Verze Delphi: 10.3
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #1 kdy: 13-12-2019, 17:57:39 »
A co že není nil? :-)
Když zavoláš Clear, ObjectList.Count vrací 0.
Jestli si na stejné objekty odkazuješ ještě sám "odjinud", z nějakých jiných proměnných, tak ty pochopitelně nil nebudou, pokud se o to sám nepostaráš.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5295
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #2 kdy: 13-12-2019, 18:14:21 »
Vytváram ich na jedinom mieste do jedinej premennej. Vytvoria sa raz. Kontroloval som to. Pri zatvorení formulára nemám žiaden memory leak. Vyskúšal som aj tieto veci
Kód: Delphi [Vybrat]
  1.   for I := FlstCustomObject.Count -1 downto 0 do
  2.   begin
  3.     Co := FlstCustomObject[I];
  4.     FreeAndNil(Co);
  5.     Co := nil;
  6. //    FlstCustomObject[I].Free;
  7. //    FlstCustomObject[I] := nil;
  8.   end;
Stále nie je nil.
Problém je v tom, že teraz mám formulár, ktorý nastavuje komponenty(v triedach).Enabled, trochu ináč než doteraz, čo mi pri druhom otvorení formulára samozrejme vyhodí chybu, lebo sú nil. Premenná existuje, ale obsah nie.
Celkovo ma to dosť mätie.
A to z dôvodu, že premenná nie je nil, vložím do nej nový objekt a bum ho. Je prázdny.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5295
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #3 kdy: 13-12-2019, 18:27:43 »
Vidím, že sa na to musím pozrieť podrobne. Aj keď som to ručne nastavil na nil, tak vyskočil problém inde. Vyzerá to presne na ten istý problém, len s iným zoznamom.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 1063
  • Karma: 47
    • Verze Delphi: 10.3
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #4 kdy: 13-12-2019, 18:30:36 »
No z ukázky, cos poslal, není vidět, co je FlstCustomObject zač.
Nicméně po dokončení toho cyklu obsahují všechny FlstCustomObject[] odkazy na už neexistující objekty.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5295
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #5 kdy: 13-12-2019, 19:46:19 »
Tento týždeň som urobil nejaké úpravy. Okrem iného som do TCustomDB doplnil pole FCustomObject. Čiastočne som na to zabudol a hlavne som si neuvedomil čo všetko je s tým spojené.
Kód: Delphi [Vybrat]
  1. constructor TCustomObject.Create...
  2.   if Assigned(ATable) then
  3.   begin
  4.     FCustomDB := TCustomDB.Create(ATable, ADataSource);
  5.     FCustomDB.CustomObject := TBasicObject(Self);  //  Tu je uloženie do druhej premennej.
  6.   end;
  7.  
  8. procedure TGlobalVar.DestroyObjects;
  9.   FlstCustomObject.Clear;  //  OwnsObjects = True
  10.  
  11. destructor TCustomObject.Destroy;
  12.   FreeAndNil(FCustomDB);
  13.  
  14. destructor TCustomDB.Destroy;
  15.   FCustomObject := nil;
Kde robím chybu? Všetko zbehne a aj tak nie je nil.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5295
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #6 kdy: 13-12-2019, 20:36:10 »
Vyhodil som priradenie FCustomDB.CustomObject := TBasicObject(Self); Použil Clear (nie cyklus) a žiadna zmena. :'(
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5295
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #7 kdy: 13-12-2019, 20:45:33 »
Dopĺňam:  FlstCustomObject: TObjectList<TCustomObject>;
TCustomObject je základný predok všetkých objektov. Pre tento prípad. Pri vytváraní dedičov TCustomObject  ich nahádžem do tohto zoznamu. Aby som nemal problém s ich ničením.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 1063
  • Karma: 47
    • Verze Delphi: 10.3
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #8 kdy: 13-12-2019, 20:58:58 »
No zavoláním FlstCustomObject.Clear je všechny zrušíš a zůstane jen ten prázdný seznam; pokud na ty rušené objekty ukazovaly ještě jiné proměnné, tak ty nadále ukazují kamsi a jakmile se pokusíš k nim přistoupit, bude problém.

Zavoláním FreeAndNil(FlstCustomObject) zrušíš všechny ty objekty a zrušíš i ten seznam jako takový.

Pomocný seznam FlstCustomObject jen kvůli tomu, abych něco nezapomněl zrušit, bych nedělal. Když něco zapomeneš zrušit, máš jen memory leak, ale pokud použíješ FlstCustomObject.Clear, na (bývalé) objekty ukazují ještě jiné proměnné a ty je použiješ, bude z toho nejspíš Access violation, náhodná data apod., což je větší průšvih

Tzn. když už si někde něco vytvoříš (třeba na formuláři), tak do OnDestroy dáš zrušení a nepotřebuješ k tomu pomocný seznam všeho, co se má zrušit.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5295
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #9 kdy: 13-12-2019, 21:05:49 »
Ten zoznam slúži na viac účelov. Hosip.
Ak objekty zničím vo FormDestroy, tak nie je žiaden problém.
Možno je chyba v tom, že to ničenie objektov volám z FormCloseQuery. Vyskúšam a uvidím.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5295
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:System.Generics.Collections.TObjectList.Clear
« Odpověď #10 kdy: 13-12-2019, 21:11:20 »
Zaujímave. Keď ich nechám zničiť pomocou zoznamu, tak je problém. Ak ich ničím jednotlivo OK. Už sa tým nebudem babrať doplním to do FromDestroy. To som si chcel ušetriť.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.