![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Хранить интерфейсы в TStrings
Ш-К © (2007-03-02 18:28:00)Есть у меня, допустим, TListBox (или любой объект у которого Items реализованы через TStringList).
Так же у меня имеется множество IDefault = interface(IInterface) интерфейсов, каждый из которых я хочу связать с TListBox.Items.
Делаю так:
iDef : IDefault;
...
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef)));
И соответственно получаю:
iDef := IDefault(Cardinal(ListBox.Items.Objects[I]));
Нет ли здесь глюков с подсчетом ссылок? И вообще как лучше реализовывать САБЖ?
DrPass (2007-03-02 20:44:00) [1]Удалено модератором
DrPass (2007-03-02 20:44:00) [2]Удалено модератором
DrPass (2007-03-02 20:44:00) [3]А это не только у него
Palladin (2007-03-02 20:10:00) [4]
> Суслик ©
как это у тебя получается?
Суслик (2007-03-02 19:31:00) [5]Удалено модератором
Примечание: трипль
Суслик (2007-03-02 19:31:00) [6]Удалено модератором
Примечание: дубль
Суслик (2007-03-02 19:31:00) [7]
> [12] Ш-К (02.03.07 19:19)
если интересно, напиши мне timokhov@gmail.com
я тебя по этому вопросу проконсультирую - вроде как я это хорошо понимаю :)
Ш-К (2007-03-02 19:19:00) [8]
> ЗЫ Можно вообще подсчет ссылок отключить :)
Вто то и дело, что мне нельзя. Я б отключил.
Суслик (2007-03-02 19:10:00) [9]Удалено модератором
Примечание: дубль
Суслик (2007-03-02 19:10:00) [10]Удалено модератором
Примечание: трипль
Суслик (2007-03-02 19:10:00) [11](ты тоже троить начал :)))
Ты спрашивал про подсчет ссылок? Я тебе сказал, что в общем случае ты делаешь неверно. Если у тебя всего три объекта, то можно и как ты делаешь. Но в общем случае нужно делать тоньше.
ЗЫ Можно вообще подсчет ссылок отключить :)
Ш-К (2007-03-02 19:04:00) [12]Да не собираюсь я создавать объекты непосредственно перед вставкой. Да еще, почему-то, через одну переменную. Они у меня живут своей жизнью: где-то создаются, где-то убиваются. Мне их надо просто отобразить в ListBox.
iDef0: IDefault;
iDef1: IDefault;
iDef2: IDefault;
...
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef0)));
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef1)));
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef2)));
Правильный вариант - хранить объекты в Items как TObject, а потом где надо через QueryInterface приводить к IDefault.
Но дело в том, что нек. объекты я вижу только как IDefault.
Суслик (2007-03-02 18:48:00) [13]Удалено модератором
Примечание: трипль
Суслик (2007-03-02 18:48:00) [14]Удалено модератором
Примечание: дубль
Суслик (2007-03-02 18:48:00) [15]все равно нельзя :)
ибо при изменении значения idef будет вызван _release для предыдущего значения - объект будет удален.
т.е.
var
iDef: IDefault; // GLOBAL VAR
...
begin
iDef := TMyClass.Create();
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef)));
iDef := TMyClass.Create();
// Все - здесь объект созданный выше умер
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef)));
end;
PS Троит меня провайдер - я не специально
Ш-К (2007-03-02 18:44:00) [16]Мысль повторенная трижды становится истиной.
iDef : IDefault - не локальная переменная. Это один из кучи разных объектов, реализующих IDefault, и не имеющих общего предка.
Суслик (2007-03-02 18:36:00) [17]так нельзя
Если ты напишешь так
var
iDef : IDefault;
begin
iDef := TMyClass.Create();
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef)));
end;
то объект будет уничтожен после end
нужно так
var
iDef : IDefault;
begin
iDef := TMyClass.Create();
iDef._AddRef();
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef)));
end;
ИЛИ так
var
iDef : IDefault;
begin
iDef := TMyClass.Create();
ListBox.Items.AddObject('bla bla', TObject(Cardinal(iDef)));
Pointer(iDef) := nil;
end;
Получать значения нужно так (как и у тебя)
var
iDef : IDefault;
begin
iDef := IDefault(Cardinal(ListBox.Items.Objects[I]));
end;
Суслик (2007-03-02 18:36:00) [18]Удалено модератором
Примечание: трипль
Суслик (2007-03-02 18:36:00) [19]Удалено модератором
Примечание: дубль