Как да унищожим масив от масиви

myarr : array [0 .. 21] of array [0 .. 21] of TColor;

по-горе е декларацията, след използването искам да унищожа масива от масив

for a := 0 to 21 do
  for b := 0 to 21 do
        myarr[a][b].destroy ;
       //myarr[a,b].destroy ;

и двата кода ми дават грешка,

E2018 Изисква се запис, обект или тип клас (Delphi)

това всъщност се прилага вътре в клас и искам да направя това, когато обектът на класа се унищожава

внедрих това, когато се изпълни щракване с мишката, предишният обект (който включва този масив) трябва да бъде унищожен и трябва да бъде създаден нов обект. Практически, когато това се случи, не трябва да остава допълнителна памет, но когато проверя това моят мениджър на задачи на Windows за всяко щракване се добавят още 200 kb, приложението ми ще прави това многократно.


person VibeeshanRC    schedule 18.11.2011    source източник
comment
Не можете и не трябва да унищожавате статичен масив.   -  person RRUZ    schedule 18.11.2011
comment
защо -1, моля, кажете причина   -  person VibeeshanRC    schedule 18.11.2011
comment
Аз също искам да знам. @vibeeshanRC, не можеш да унищожиш TColor. ако беше масив от класове, можете, но TColor не е клас. Можете ли да публикувате повече код?   -  person Arjen van der Spek    schedule 18.11.2011
comment
Благодаря, но мислех, че tcolor е клас и трябва да освободя тези обекти   -  person VibeeshanRC    schedule 18.11.2011
comment
TColor е просто цяло число. Това е тип стойност и не е необходимо да се унищожава. Колкото и да си струва, никога не се обаждайте на Destroy, вместо това се обадете на Free. Но този съвет е за когато имате обект.   -  person David Heffernan    schedule 18.11.2011
comment
@vibeeshanRC Дейвид Хефернан вече ви даде отговора и съвет за бъдещето, сега позволете ми да ви дам съвет, задръжте клавиша CTRL и щракнете с мишката върху TColor и IDE ще ви отведе до декларацията извън типа, същото важи и за други типове, да предположим, че имате декларация на var като var a: TStringList;, задръжте CTRL и щракнете с мишката върху TStringList, за да намерите нейната дефиниция, по този начин можете да разберете дали дадена променлива трябва да бъде освободена или не, също така може да искате да използвайте FreeAndNil( AVARIABLE), вместо да извиквате .Free   -  person    schedule 18.11.2011


Отговори (1)


TColor е целочислен тип, тип стойност и не е клас. Съответно не е необходимо да се освобождава. Дефиницията на TColor е

TColor = -$7FFFFFFF-1..$7FFFFFFF;

Така че вашият масив е почти еквивалентен, за целите на разпределението, на

myarr: array [0..21] of array [0..21] of Integer;

Не е необходимо елементите на такъв масив да се освобождават. Самият масив ще бъде освободен автоматично, независимо къде го декларирате (глобален, локален, член на клас, член на запис). Това също е ценностен тип.

Най-добрата улика, че не е необходимо да освобождавате TColor е, че никога не сте го създавали. Разпределенията и освобождаванията винаги са сдвоени.


Като настрана, никога не трябва да се обаждате директно на Destroy. Пишете Destroy в код само когато имплементирате отменения деструктор за клас, т.е. по следния начин:

destructor Destroy; override;
...
destructor TMyClass.Destroy;
begin
  FMyObject.Free;
  inherited;
end;

Когато дойдете да унищожите обект, трябва да извикате Free върху него. Не не се обаждайте директно на Destroy. Защо не? Е, Free се изпълнява така:

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

Изявлението if означава, че ако имате препратка към обект, която е nil, тогава е безопасно да извикате Free върху него, без да се страхувате от възникване на изключение.

Това е важно в случай, че се повдигне изключение в конструктор. Когато това се случи, деструкторът се извиква. Ако конструкторът е завършил само частично, тогава някои полета все още ще бъдат nil. Извикването на Free ни позволява да напишем чист деструкторен код. Без това удобство всички наши деструктори биха изглеждали така:

destructor TMyClass.Destroy;
begin
  if FMyObject3<>nil then
    FMyObject3.Destroy;
  if FMyObject2<>nil then
    FMyObject2.Destroy;
  if FMyObject1<>nil then
    FMyObject1.Destroy;
  inherited;
end;
person David Heffernan    schedule 18.11.2011
comment
Благодаря, въпросът ми всъщност не е точен, но вашият отговор ми изясни какво трябва да направя - person VibeeshanRC; 18.11.2011