当我尝试使用DocumentElement
的{{1}}时,我总是遇到访问冲突。我根据某个文件的存在创建XMLDocument
。
错误消息
Project project1.exe引发了异常类EAccessViolation 消息'模块中地址0047B152的访问冲突 'project1.exe'Read of Address B1D59357'
我的代码
XMLDocument
由于对象或指针的初始化不正确而导致访问冲突,这是否意味着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.
未被初始化?
答案 0 :(得分:10)
您正在将nil
传递给TXMLDocument.Create
。执行此操作时,对象的行为类似于TInterfacedObject
。它的生命周期由接口引用计数管理。但是你没有持有对接口的引用。
documentation详细介绍了这一点。
在没有所有者的情况下创建TXMLDocument时,它的行为类似于接口对象。那就是全部 释放对其接口的引用,自动释放TXMLDocument实例。但是,当使用所有者创建TXMLDocument时,它的行为与任何其他组件一样,并由其所有者释放。
如果启用调试DCU并在TXMLDocument.Destroy
中设置断点,则可以在访问冲突之前观察被销毁的对象。
通过以下任一方式解决问题:
XMLDocument1
声明为IXMLDocument
。请确保您执行其中一项,但不要同时执行这两项操作!
答案 1 :(得分:3)
正如David所说,只是将XMLDocument1声明从XMLDocument1: TXMLDocument
更改为XMLDocument1: IXMLDocument
即可解决问题。您的问题与Using TXmlDocument