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;

2 番目の if ステートメントで、「モジュール 'GoogleDocsApiTests.exe' のアドレス 0061A55C でアクセス違反が発生しました。アドレス 00000049 の読み取り」というアクセス違反が発生し、ReturnValue と ReturnValue.ChildNodes のウォッチを見ると、ReturnValue がResult が TGoogleDocsApi.GetEntries メソッドで行ったのと同じアドレスですが、ReturnValue.ChildNodes の監視でアクセス違反が発生し、TGoogleDocsApi.GetEntires メソッドでは、Result.ChildNodes に有効なアドレスがあり、そのプロパティが入力されています。

私には、Delphi が ChildNodes プロパティをどこかでリリースしているように見えますが、ReturnValue がまだそれを参照している必要があるため、意味がありません。

何が起こっているのでしょうか?

4

1 に答える 1

21

of で呼び出しTXMLDocument.Createています。つまり、その寿命はインターフェイス参照カウントによって制御されます。それが機能するためには、実際にインターフェイスを使用する必要があります。のタイプをに変更して参照を維持します。そうしないと、予期しないときに VCL の内部の何かによって解放されます。OwnernilxmlDocIXMLDocument

于 2012-05-21T21:54:29.473 に答える