8

我正在使用 Delphi XE2 为 Googledocs api 开发一个 Delphi 包装器。我使用 XML 数据绑定向导生成了所有类。这使用代码更容易解​​释,所以这是我的测试调用的函数。

function TGoogleDocsApi.GetEntries : IXMLEntryTypeList;
var
  httpHelper : IHttpHelper;
  xml, url : string;
  xmlDoc : TXmlDocument;
  ss : TStringStream;
  feed : IXmlFeedType;
begin
  ss := TStringStream.Create;
  httpHelper := THttpHelper.Create;
  if(fToken.IsExpired) then
    fToken.Refresh(fClientId,fClientSecret);
  url := BaseUrl + 'feeds/default/private/full?showfolders=true&access_token='+fToken.AccessToken+'&v=3';
  xml := httpHelper.GetResponse(url);
  ss.WriteString(xml);
  ss.Position := 0;
  xmlDoc := TXmlDocument.Create(nil);
  xmlDoc.LoadFromStream(ss);
  feed := GoogleData2.Getfeed(xmlDoc);
  Result := feed.Entry;
end;

现在,在点击“end”时,Result.ChildNodes 在内存中有一个地址,其计数为 20。IXMLEntryTypeList 是 IXMLNodeCollection 的子接口。

现在这是我的测试:

procedure TestIGoogleDocsApi.TestGetEntries;
var
  ReturnValue: IXMLEntryTypeList;
begin
  ReturnValue := FIGoogleDocsApi.GetEntries;
  if(ReturnValue = nil) then
    fail('Return value cannot be nil');
  if(ReturnValue.ChildNodes.Count = 0) then
    fail('ChildNodes count cannot be 0');
end;

在第二个 if 语句中,我得到一个访问冲突,说“模块 'GoogleDocsApiTests.exe' 中地址 0061A55C 的访问冲突。读取地址 00000049”,当我查看 ReturnValue 和 ReturnValue.ChildNodes 的手表时,我看到 ReturnValue 有与 TGoogleDocsApi.GetEntries 方法中的 Result 相同的地址,但它给了我对 ReturnValue.ChildNodes 和 TGoogleDocsApi.GetEntires 方法的手表的访问冲突,Result.ChildNodes 具有有效的地址并且其属性已填写。

对我来说,Delphi 似乎正在沿线某处释放 ChildNodes 属性,但这对我来说没有意义,因为 ReturnValue 仍然应该引用它(我认为)应该保留它。

任何想法可能会发生什么?

4

1 回答 1

21

You're calling TXMLDocument.Create with an Owner of nil. That means its lifetime is controlled via interface reference counting. In order for that to work, you need to actually use interfaces. Change xmlDoc's type to IXMLDocument to maintain a reference, or else something internal to the VCL will free it when you're not expecting it.

于 2012-05-21T21:54:29.473 回答