我在一个通用单元中申明了一个自定义类:
unit Unit_Public;interfaceuses
  Windows, Messages,Forms,Dialogs,SysUtils,IniFiles,StdCtrls,Controls,
  DB, ADODB,ComCtrls,StrUtils,Imm,Variants;
type
  TPubComBoBOx = class(Tobject)
  private
    PID: string;
    PName: String;
  end;
type
  TPubComBoBOx = class(Tobject)
  private
    PID: string;
    PName: String;
  end;
  Function LoadNameToComBoBox(NowCBB:TComboBox):byte; //打开商品表并显示到:NowCBB
  function GetComBoBoxSelectedStringIDValue(OBCB:TComboBox):string; //获取COMMBOBOX中选中内容的ID值implementation
  Function LoadNameToComBoBox(NowCBB:TComBoBox):byte;
  var
  ADOQuery: TADOQuery;
  ObjPB: TPubComBoBOx;
  i,f: integer;
begin
  Result := 1;
  NowCBB.Items.Clear;
  ADOQuery := TADOQuery.Create(Application);
  try
    ADOQuery.Connection := Dm.ACN;
    ADOQuery.SQL.Add('select ID,Name from SHOP_T order by Name);
    ADOQuery.Open;
    ADoQuery.First;
    ADoQuery.DisableControls;
    while not ADOQuery.Eof do
    begin
      ObjPB       := TPubComBoBOx.Create;
      ObjPB.PID   := ADOQuery.FieldByName(FieldStr1).AsString;
      ObjPB.PName := ADOQuery.FieldByName(FieldStr2).AsString;
      NowCBB.Items.AddObject(ObjPB.PName,ObjPB);
      //  FreeAndNIl(ObjPB); //在此释放的话,在别的单元引用GetComBoBoxSelectedStringIDValue函数时将报引用一个
      ADOQuery.Next;         //已经释放类错误,但不释放的话肯定会有内存溢出的,我该在哪里释放呢?  
    end;
      Result := 0;
  end;
  finally
    ADOQuery.Close;
    ADOQuery.Free;
  end;
end;function GetComBoBoxSelectedStringIDValue(OBCB:TComboBox):string; //获取COMMBOBOX中选中内容的ID值
var
  GBSID : TPubComBoBOx;
begin
  Result := '';
  if (OBCB.ItemIndex<0) then  exit;
  GBSID:=(OBCB.Items.Objects[OBCB.ItemIndex] as  TPubComBoBOx);
  result:=GBSID.PID;
end;////////////////////////////////////////////////
在别的单元调用:GetComBoBoxSelectedStringIDValue(Combobox1) 时如果在LoadNameToComBoBox已经释放,肯定会报引用错误码,我访怎么释放从而不会发生内存溢出呢?

解决方案 »

  1.   

    首先你不应该在while not ADOQuery.Eof do中频繁创建自定义类,你创建一次就够了,在循环外创建,循环结束,把他释放
      

  2.   

    我现在已改为在循环外创建,循环结束释放
    但在其它单元引用GetComBoBoxSelectedStringIDValue(Combobox1) 时还是会报:
    Invalid class typecast如果要在调用单元释放的话,具体该怎么释放呢?
      

  3.   

    Function LoadNameToComBoBox(NowCBB:TComBoBox; OwenrList: TObjectList):byte; 
      var 
      ADOQuery: TADOQuery; 
      ObjPB: TPubComBoBOx; 
      i,f: integer; 
    begin 
      Result := 1; 
      NowCBB.Items.Clear; 
      ADOQuery := TADOQuery.Create(Application); 
      try 
        ADOQuery.Connection := Dm.ACN; 
        ADOQuery.SQL.Add('select ID,Name from SHOP_T order by Name); 
        ADOQuery.Open; 
        ADoQuery.First; 
        ADoQuery.DisableControls; 
        while not ADOQuery.Eof do 
        begin 
          ObjPB      := TPubComBoBOx.Create; 
           OwenrList.Add(ObjPB)//把创建对象扔到OwenrList,由其释放,可把OwenrList看作自动回收站
          ObjPB.PID  := ADOQuery.FieldByName(FieldStr1).AsString; 
          ObjPB.PName := ADOQuery.FieldByName(FieldStr2).AsString; 
          NowCBB.Items.AddObject(ObjPB.PName,ObjPB); 
          //  FreeAndNIl(ObjPB); //在此释放的话,在别的单元引用GetComBoBoxSelectedStringIDValue函数时将报引用一个 
          ADOQuery.Next;        //已经释放类错误,但不释放的话肯定会有内存溢出的,我该在哪里释放呢?  
        end; 
          Result := 0; 
      end; 
      finally 
        ADOQuery.Close; 
        ADOQuery.Free; 
      end; 
    end; 
      

  4.   


    TObjectList,引用单元见帮助,其可以帮你管理对象。类似于TComponent管理对象列表的功能。
      

  5.   

    一样的,我还是得到LoadNameToComBoBox中释放OwenrList呀,这样在其它单元引用GetComBoBoxSelectedStringIDValue(Combobox1) 时还是会报: 
    Invalid class typecast 
      

  6.   

    现在只有把ObjPB: TPubComBoBOx; 在通用单元里面定义成全局的
    然后在调用窗体关闭的时候FreeAndNIl(ObjPB);
    这样就应该不会发生内存泄露.
    不知道还有其它方法不?
      

  7.   

    是一组对象,而不是仅仅一个吧,除了我上面提到的方法,另外一个方法是在窗体释放的时候
    for i := 0 to NowCBB.Items.Count - 1 do
      NowCBB.Items.Objects[i].Free
      

  8.   

    自己解决了
    1.必须在循环内创建,不然多个COMBOBOX时获取不了ID
    2.在调用窗体退出时用以下过程手动释放
       for i:=0 to OBCB.Items.Count -1 do
        (OBCB.Items.Objects[i] as  TPubComBoBOx).Free;
    还是谢谢各位。