当我尝试使用 XMLDocument
的 DocumentElement
时,总是遇到访问冲突。我根据某个文件的存在创建 XMLDocument
。
错误消息
Project project1.exe raised exception class EAccessViolation with message 'Access violation at address 0047B152 in module 'project1.exe'.Read of Address B1D59357'
我的代码
unit XMLBase;
interface
uses
SysUtils, xmldom, XMLIntf, XMLDoc, Forms;
type
TXMLbase = class
private
{ Private declarations }
public
XMLDocument1: TXMLDocument;
root: IXMLNode;
constructor Create;
end;
var
fn: string;
implementation
constructor TXMLbase.Create;
begin
fn := ChangeFileExt(Application.ExeName, '.xml');
XMLDocument1 := TXMLDocument.Create(nil);
XMLDocument1.Options := [doNodeAutoIndent];
XMLDocument1.Active := False;
//optional, is used to indent the Xml document
if FileExists(fn) then
begin
XMLDocument1.LoadFromFile(fn);
XMLDocument1.Active:= True;
root := XMLDocument1.DocumentElement; //<<--- Access Voilation
end
else
begin
XMLDocument1.Active := False;
XMLDocument1.XML.Text := '';
XMLDocument1.Active := True;
root := XMLDocument1.AddChild('Settings');
end;
XMLDocument1.SaveToFile(fn);
end;
end.
由于对象或指针初始化不当而导致访问冲突,这是否意味着 XMLDocument
未初始化?
最佳答案
您正在将 nil
传递给 TXMLDocument.Create
。当您执行此操作时,该对象的行为类似于 TInterfacedObject
。它的生命周期由接口(interface)引用计数管理。但您没有持有对接口(interface)的引用。
documentation对此进行了一些详细介绍。
When TXMLDocument is created without an Owner, it behaves like an interfaced object. That is, when all references to its interface are released, the TXMLDocument instance is automatically freed. When TXMLDocument is created with an Owner, however, it behaves like any other component, and is freed by its Owner.
如果启用调试 DCU 并在 TXMLDocument.Destroy
中设置断点,您可以观察到对象在访问冲突之前被销毁。
通过以下任一方式解决问题:
- 创建文档时传递所有者。
- 切换到使用接口(interface)来引用对象。即将
XMLDocument1
声明为IXMLDocument
。
一定要确保执行其中一项或多项,但不要同时执行两项!
关于delphi - 在 XMLDocument 中使用 DocumentElement 时发生访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14031756/