Вниз
Скачать: CL | DM;

Цикл по элементам 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 вся ветка

Скачать: CL | DM;



Память: 0.47 MB
Время: 0.006 c
2-1307467358
Exterr
2011-06-07 21:22
2011.09.25
Создание панели в рабочем столе


15-1307073974
kuzja52
2011-06-03 08:06
2011.09.25
узнать пароль пока открыт браузер


2-1307440318
uniken1
2011-06-07 13:51
2011.09.25
захват выводв SSH2


11-1237556635
BMouradov
2009-03-20 16:43
2011.09.25
AnsiCompare и StrList.Find


2-1307420263
Sergey
2011-06-07 08:17
2011.09.25
Как перевести каретку в мемо в конец строки?




   Наверх