![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблемы с XML [D6]
A. N. Onim © (2002-09-10 11:25:00)Помнится, под MSVC работал с MSXML парсером и неоднократно сталкивался с Гамлетовским вопросом - освобождать или не освобождать полученный интерфейсный указатель дитя (Child) при просмотре XML узла? Ответ был, как ни странно, нет. Release был не нужен.
Перешёл на Delphi, к компоненте TXMLDocument.
Беру корневой узел:
...
public:
m_pDocument: TXMLDocument;
...
procedure Test()
var
Saved: IXMLNode;
begin
m_pDocument := TXMLDocument.Create(nil);
m_pDocument.DOMVendor := GetDOMVendor ("MSXML");
m_pDocument.LoadFromFile("pos.xml");
Saved := m_pDocument.Node.ChildNodes[0];
// так просто тестик, что работает!
Form1.Caption := Saved.NodeName;
При выходе! БА - БАХ ! Access Violation
end;
Как я понимаю, был вызван Release на локальной копии интерфейса Saved при разрушении. Ладно. Добавлю в код _Addref() для Saved - не помогает. Двойной _Addref() выправляет ситуацию, но... Всё падает при уничтожении документа :( По ходу парсеринга такое г..о лезет аж жуть. Типа, у узла есть дети (HasChilds = true), а сами дети NodeChilds - Access Violation? Скажите, что это за гемор такой???
Ihor Osov'yak (2002-09-10 13:02:00) [1]Еще когда-то очень давно говорось, и не единыжды, не работайте одновременно по обьектным и интерфейсным ссылкам. Геморою не оберетесь. Это так, философия.
А теперь по существу. Интерфейсы в делфи относятся к "автоуничтожаемым" обьектам (тут термин обьект мной употреблен для для обозначения инстанции какого то класса, а для обозначения некой програмной субстанции).
Механизм "автоуничтожения" по отношению к интерфейсам работает так:
компилятор неявно вызывает _release всякий раз, когда интерфейсная ссылка уходит из области видимости или когда ей присваеватся новое значение (_release вызывается для старой ссылки). _Addref вызывается неявно при операции присваивания ...
Мораль здесь такова - не надо в делфи _release и _Addref явно вызывать. А если возникнет такое желание - хорошенько подумать, почитать книжки, попить водички и пт и снова подумать. И так до тех пор, пока это желание не пропадет.
Далее. Естественно, рано или позно будет вызван _release, который приведет к уничножению обьекта. А если мы еще имеем обьектную ссылку - как в вашем случае - то обьект уничтожается, ссылка на него смотрит, мы по ней чего то делаем - со всеми последствиями. Надеюсь, теперь понятно, почему я говорил, что очень неприветствуется одновременная работа по обьктным и по интервейсным ссылкам. Если все же очень нужно - то нужно предусмотреть "удерживающую" интерфейсную ссылку. Которую потом не забыть обнулить...
A. N. Onim (2002-09-10 12:36:00) [2]Создавать документ надо было обязательно с нениловским Parent"ом Вопрос исчерпан. Чёртов Delphi!