Форум: "Начинающим";
Текущий архив: 2011.09.25;
Скачать: [xml.tar.bz2];
Вниз
Цикл по элементам TInterfaceList Найти похожие ветки
← →
harisma © (2011-06-06 11:40) [0]Мне необходимо организовать цикл по элементам интерфейсного листа и при нахождении нужных элементов их выбросить из него. С этой целью написал следующую процедурку:
procedure CloseProtocols(const AProtocolID: WideString);
var
i: Integer;
LProtocolID: AnsiString;
IProtocol: IS4VPAProtocols;
begin
FProtocolList.Lock;
try
if (AProtocolID = "") then
begin
FProtocolList.Clear;
Exit;
end
for i := FProtocolList.Count - 1 downto 0 do
try
if (FProtocolList[i].QueryInterface(IS4VPAProtocols, IProtocol) = S_OK) then
begin
if (AProtocolID <> "") then
LProtocolID := FloatToString(IProtocol.ProtocolID);
if (AProtocolID = "") or (AProtocolID = LProtocolID) then
begin
IProtocol.CloseMean;
IProtocol.Server := nil;
if (AProtocolID <> "") then
FProtocolList.Remove(IProtocol);
end;
end;
except
end;
finally
FProtocolList.Unlock;
end;
end;
Но вот проблема: После того, как первый, удовлетворяющий условие элемент найден и удален из списка, попытка взять QueryInterface у следующего элемента списка приводит к AccessViolation.
Никак не пойму, в чем же проблема? Цикл вроде правильный. В списке присутствует 2 интерфейса. Прошу помощи...
← →
Ega23 © (2011-06-06 12:07) [1]
> FProtocolList.Remove(IProtocol);FProtocolList.Delete(i)
← →
harisma © (2011-06-06 12:17) [2]Так не помогает. Так и было у меня первоначально.
← →
KSergey © (2011-06-06 12:29) [3]FProtocolList.Remove(IProtocol);
Есть уверенность, что из списка здесь удаляется именно текущий i-й элемент? или я неправильно понимаю принцип работы TInterfaceList?
← →
makvell (2011-06-06 13:37) [4]Предположение: Мы идем по i, длинна списка = 2, нашли первый, удалили. Второй стал первым, а мы пытаемся взять по i следующий, которого какбы и нет.
← →
makvell (2011-06-06 13:38) [5]А... там даунту. Сорри, проглядел :(
← →
anonims (2011-06-06 14:47) [6]
> IProtocol.Server := nil;
отключаем интерфейсный объект от сервера?
сам интерфейс остается.
Если другой интерфейс из списка тоже на этом объекте. то AV вероятно.
Iprotokol:=nil; наверное так?
← →
harisma © (2011-06-06 15:55) [7]Ошибка решилась. Проблема была в том, что когда я ЗАПОЛНЯЛ этот список интерфейсами, сами интерфейсы не разрушал в той процедуре, где заполнял. Другими словами было:
procedure ...
var
LProtocol: IProtocol;
...
begin
...
Lprotocol := CreateComObject(...)
LProtocol.Init.
FProtocolList.Add(Lprotocol);
end;
стало
procedure ...
var
LProtocol: IProtocol;
...
begin
...
Lprotocol := CreateComObject(...)
LProtocol.Init.
FProtocolList.Add(Lprotocol);
LProtocol := nil; - это я дописал
end;
← →
_Юрий (2011-06-06 20:27) [8]
> Ошибка решилась.
Ошибка скрылась. Данный код
> LProtocol := nil; - это я дописал
и так будет вызван компилятором сразу после выхода из локальной процедуры.
И никакое это не "разрушение интерфейса". Это уменьшение счетчика ссылок, который в данном случае до нуля не дойдет потому, что есть еще ссылка в листе.
Похоже, ты где-то память попортил.
← →
harisma © (2011-06-07 10:35) [9]
> до нуля не дойдет
А вот и не правда. Хотя, я ведь не привел полный текст процедуры. В моем случае именно и происходило разрушение интерфейса, не смотря на то что ссылка на него была в листе.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2011.09.25;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.004 c