1

使用这样的循环制作组件后,如何正确释放组件?如果我像现在这样释放它,我会得到一些 GETMEM.INC 异常。我来自印地,所以我不太了解 ICS。

谢谢

  const
    URLs : array[0..3] of string =
    (
      'http://www.example.com',
      'http://www.example.com',
      'http://www.example.com',
      'http://www.example.com'
    ) ;

    var
      Output: array of TStringList;
      S: array of TMemoryStream;
      Async: array of TSslHttpCli;
    implementation

    procedure RequestDone(Sender: TObject; RqType: THttpRequest;
      ErrCode: Word);
    begin
        with Sender as TSSLHTTPCLI do  begin
          S[Tag].Position:=0;
          Output[Tag].LoadFromStream(S[Tag]);
        end;
      end;


    procedure TForm1.Button1Click(Sender: TObject);
    var
    i:integer;
    begin
        for i := 0 to High(URLS) do begin
           S[i]:=TMemoryStream.Create;
           Output[i]:=TStringList.Create;
           Async[i]:=TSslHttpCli.Create(nil);
           Async[i].Tag:=i;
           Async[i].FollowRelocation:=true;
           Async[i].NoCache:=true;

           Async[i].SocketFamily:=sfAny;
           Async[i].OnRequestDone:=RequestDone;
           Async[i].RcvdStream:=S[i];
           Async[i].URL:= URLs[i];
           Async[i].MultiThreaded:=true;
           Async[i].GetASync;
        end;
    end;

    procedure TForm1.Button4Click(Sender: TObject);
    var
    i:integer;
    begin
        for i := 0 to High(URLS) do begin
           Output[i].Free;
           Async[i].RcvdStream.Free;
           Async[i].Free; // << -- EXCEPTION
           //  S[i].Free;
        end;
    end;
4

1 回答 1

2

Result您永远不会为、Asynch或分配任何内存S。您需要先SetLength对它们中的每一个进行操作,然后才能将任何东西放入其中(或将任何东西取出)。

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
  SetLength(Result, Length(URLS));
  SetLength(S, Length(URLS));
  SetLength(Asynch, Length(URLS));

  for i := 0 to High(URLS) do begin
    S[i]:=TMemoryStream.Create;
    Result[i]:=TStringList.Create;
    Async[i]:=TSslHttpCli.Create(nil);

    // etc.

  end;
end;

顺便说一句,Result对于变量来说,这是一个糟糕的名称,尤其是一个全局范围的变量。它是编译器自动生成的函数的返回值,并且在函数中以外的任何地方使用都会使您的代码难以阅读。看这个,例如:

var
  Result: string = '';

procedure AddToReslt(CharToAdd: Char);
begin
  // Many many lines of code
  // go in here. Maybe a few loops
  // of if statements.
  Result := Result + CharToAdd;
end;

function DoSomeMath: Integer;
begin
  // Some really complex numeric code, maybe
  // calculating the value of `pi` to the 900th
  // digit 
  Result := 2 * 2;
end;

现在很快 - 记住它们每个都包含大量代码 - 哪个是函数,哪个是过程?

于 2012-12-13T15:52:07.693 回答