如何在不释放内容的情况下释放ObjectList

时间:2013-11-01 14:20:57

标签: delphi delphi-xe2

我有一个填充的ObjectList。然后在对象中更改细节。现在我需要释放ObjectList,但是当我这样做时也会释放列表中的对象。如何在不释放对象的情况下释放此列表?

示例代码:

{Gets starting cards and put them into the correct rows}
//***************************************************************************
procedure TFGame.GetStartingCards;
//***************************************************************************
const
  ManaTypes : array [0..3] of string = ('Lava','Water','Dark','Nature');
var
   i: integer;
   z:integer;
   Cards: TObjectList<Tcard>;
begin
  Cards := TObjectList<TCard>.Create;
  z:=0;
  {add all tcards (Desgin ) to this list in order Lava,water,dark,nature }
  cards.Add(cardLava1);
  cards.Add(cardlava2);
  cards.Add(cardlava3);
  cards.Add(cardlava4);
  cards.Add(cardwater1);
  cards.Add(cardwater2);
  cards.Add(cardwater3);
  cards.Add(cardwater4);
  cards.Add(carddark1);
  cards.Add(carddark2);
  cards.Add(carddark3);
  cards.Add(carddark4);
  cards.Add(cardnature1);
  cards.Add(cardnature2);
  cards.Add(cardnature3);
  cards.Add(cardnature4);
 //get data from DB
  for i := 0 to Length(ManaTypes) - 1 do
  begin
    with adoquery1 do
    begin
      close;
      sql.Clear;
      sql.Add('SELECT TOP 4 * FROM Cards WHERE Color = "'+ManaTypes[i]+'" ORDER BY Rnd(-(1000*ID)*Time())');
      open;
    end;

      {return the result of everything for giving mana type.. }
     if adoquery1.RecordCount = 0 then
        Showmessage('Error no cards in db');
     adoquery1.First;

     while not adoquery1.Eof do
     begin
        cards[z].Cname := adoquery1.FieldByName('Name').AsString;
        cards[z].Ccost := adoquery1.Fieldbyname('Cost').AsInteger;
        cards[z].Ctext := adoquery1.FieldByName('Text').AsString;
        cards[z].Ccolor := adoquery1.FieldByName('Color').AsString;
        cards[z].Cinplay := false; //in the play area
        if adoquery1.fieldbyname('Power').asstring <> '' then
            cards[z].Cpower := adoquery1.FieldByName('Power').AsInteger;
        if adoquery1.fieldbyname('Def').asstring <> '' then
            cards[z].Cdef := adoquery1.FieldByName('Def').AsInteger;
        if adoquery1.FieldByName('Type').AsString = 'Spell' then
           cards[z].Cspell := true
        else
           cards[z].Cspell := false;
        if adoquery1.FieldByName('Target').AsString = 'yes' then
            cards[z].SetTargetTrue
        else
            cards[z].settargetfalse;

        //based on color change background
        cards[z].Background.LoadFromFile(format('%s\pics\%s.png',[maindir,cards[z].Ccolor]));
       adoquery1.Next;
       cards[z].repaint;
       z:=z+1;
     end;

  end;
 //cards.Free; if i free this it removes all the cards added to it..
end;

1 个答案:

答案 0 :(得分:4)

TObjectList<T>的{​​{3}}会收到一个名为AOwnsObjects的参数,该参数指定谁负责释放对象。如果您通过True,那么列表就有责任。否则,责任仍由你承担。

constructor Create(AOwnsObjects: Boolean = True); overload;

该参数的默认值为True,我假设您在不指定该参数的情况下调用构造函数。因此,您将获得默认行为 - 列表拥有其成员。

constructor这样说:

  

AOwnsObjects参数是一个布尔值,指示对象条目是否归列表所有。如果对象是拥有的,则从列表中删除条目时,将释放该对象。 OwnsObjects属性是根据此参数的值设置的。默认值为true。

现在,如果您希望此特定列表实例不释放其成员,那么使用TObjectList<T>几乎无法获得。你也可以使用普通的documentation