Форум: "Основная";
Текущий архив: 2003.09.04;
Скачать: [xml.tar.bz2];
ВнизИнтерфейсы Найти похожие ветки
← →
D_V_P (2003-08-21 17:02) [0]Вызывается ли метод Release при выходе переменной типа интерфейс из области видимости. И что происходит при присвоении такой переменной значения nil? И чему равен счетчик ссылок при создании самого объекта (Напр., потомка TComponent)?
← →
Skier (2003-08-21 17:07) [1]
> Вызывается ли метод Release при выходе переменной типа интерфейс
> из области видимости.
Интерфейс вообще "прибивается"
> И что происходит при присвоении такой переменной значения
> nil?
"прибивается"
> И чему равен счетчик ссылок при создании самого объекта
> (Напр., потомка TComponent)?
-1
TComponent считает ссылки только для COM
Смотрим код :
function TComponent._AddRef: Integer;
begin
if FVCLComObject = nil then
Result := -1 // -1 indicates no reference counting is taking place
else
Result := IVCLComObject(FVCLComObject)._AddRef;
end;
← →
D_V_P (2003-08-21 17:32) [2]А что означает "прибивается"? Насколько я понимаю, при получении интерфеса в случае не COM-объекта фактически происходит просто преобразование типа объекта, реализующего интерфес. Происходит ли что-то с объектом (не COM), реализующим этот интерфейс.
← →
Skier (2003-08-21 17:37) [3]>D_V_P © (21.08.03 17:32) [2]
> А что означает "прибивается"?
Освобождается выделенная память.
Аналогично переменным с управляемым временем жизни
> Насколько я понимаю, при получении интерфеса в случае не
> COM-объекта фактически происходит просто преобразование
> типа объекта, реализующего интерфес.
Не правильно понимаешь.
← →
Юрий Федоров (2003-08-21 17:52) [4]Компилятор обеспечивает автоматические вызовы _AddRef и _Release при присвоении \ потере ссылки на интерфейс.
С преобразованием типа ты загнул - ты никогла не сможешь получить указатель на объект из указателя на интерфейс(если только специальный метод завести, но это бред :-)).
Что касается автоматического разрушения объекта при потере на него всех ссылок - достаточно посмотреть стандартную реализацию метода TInterfacedObject._Release :
Result := InterlockedDecrement(FRefCount);
if Result = 0 then
Destroy;
Вроде все понятно? При обнулении счетчика вызывется деструктор.
При другой реализации _Release память может и не освободиться
← →
Vuk (2003-08-21 18:13) [5]to Skier:
>TComponent считает ссылки только для COM
Методы _AddRef и _Release в TComponent реализованы так для того, чтобы не нарушать принятую для TComponent и его наследников технологию управления временем жизни дочерних объектов.
>> А что означает "прибивается"?
>Освобождается выделенная память.
Память не освобождается. При выходе из области видимости вызывается _Release. А уж освобождать память или нет - это на основании вызова _Release решает сам объект, реализующий интерфейс.
to Юрий Федоров:
>если только специальный метод завести, но это бред
Не такой уж и бред. Вот фрагмент classes.pas
...
IInterfaceComponentReference = interface
["{E28B1858-EC86-4559-8FCD-6B4F824151ED}"]
function GetComponent: TComponent;
end;
....
TComponent = class(TPersistent, IInterface, IInterfaceComponentReference)
....
← →
Skier (2003-08-21 18:20) [6]>Vuk © (21.08.03 18:13) [5]
> Методы _AddRef и _Release в TComponent реализованы так для
> того, чтобы не нарушать принятую для TComponent и его наследников
> технологию управления временем жизни дочерних объектов.
И что ?
> Память не освобождается. При выходе из области видимости
> вызывается _Release. А уж освобождать память или нет - это
> на основании вызова _Release решает сам объект, реализующий
> интерфейс.
Уверен ?
← →
Юрий Федоров (2003-08-21 18:22) [7]>>Skier © (21.08.03 18:20) [6]
>>Уверен ?
Дело говорит :-)
← →
vuk (2003-08-21 18:24) [8]to Skier:
>И что ?
Ничего. Просто это надо понимать, если реализовывать интерфейсы в наследниках TComponent.
>Уверен ?
Зуб даю. :o) При выходе из области видимости вызывается _IntfClear, а уже оттуда - _Release. А если мы посмотрим на TInterfacedObject._Release, то там видно, что решение о вызове деструктора принимает сам экземпляр. Фрагмент этого кода у Юрия Федорова приведен.
← →
Skier (2003-08-21 18:30) [9]
> Зуб даю. :o) При выходе из области видимости вызывается
> _IntfClear, а уже оттуда - _Release. А если мы посмотрим
> на TInterfacedObject._Release,
OK.
Но мы ведь рассматриваем случай для TComponent
А как в этом случае ?
← →
D_V_P (2003-08-21 18:34) [10]Насчет преобразования типа я был не прав.
Но где происходит выделение памяти при получении интерфейса?
При обращении к методам интерфейса происходит обращение
к некой "части" объекта, реализующей запрашиваемый интерфейс
(добавлю для осторожности - насколько я понимаю :). Если
это не так, то что реально происходит при получении интерфейса?
Что разрушается при "умирании" переменной типа интерфейс?
В реализации TObject.GetInterface места, где выделяется память
я не нашел.
← →
Юрий Федоров (2003-08-21 18:43) [11]type
ISomeInterface = interface
...
end;
TSomeInterface = class(TInterfacedObject, ISomeInterface)
...
end;
function GetSomeInterface : ISomeInterface;
begin
Result:=TSomeInterface.Create; //Память выделяется здесь !!!
end;
← →
D_V_P (2003-08-21 18:45) [12]Пока смотрел исходники и писал ответ многое пропустил. Теперь все ясно. Спасибо.
← →
vuk (2003-08-21 18:51) [13]to Skier:
>Но мы ведь рассматриваем случай для TComponent
Если экземпляр наследника от TComponent не используется совместно с COM, то счетчик не ведется и _Release игнорируется.
to D_V_P:
>Но где происходит выделение памяти при получении интерфейса?
Нигде. Для поддержки интерфейсов никакая дополнительная память не нужна.
>что реально происходит при получении интерфейса?
Вкратце так:
1. В таблице интерфейсов класса ищется (путем сравнения GUID) определение нужного интерфейса.
2. Исходя из найденных данных возвращается либо Self+смещение, указанное в данных либо, если реализация интерфейса делегирована, получается через делегирующее свойство или поле.
>Что разрушается при "умирании" переменной типа интерфейс?
Ничего не разрушается. Просто вызывается _Release.
← →
Skier (2003-08-21 19:09) [14]>vuk © (21.08.03 18:51) [13]
Т.е. поскольку ссылки не считаются интерфейс в этом случае
не освободится ?
← →
Юрий Федоров (2003-08-21 19:11) [15]>>Skier © (21.08.03 19:09) [14]
Так скажем объект не освободится (не будет вызван деструктор)
← →
Skier (2003-08-21 19:15) [16]>Юрий Федоров © (21.08.03 19:11) [15]
> Так скажем объект не освободится
Угу. Поправка принимается ! :)
Надо бы мне поосторожней с определениями...
← →
vuk (2003-08-21 19:15) [17]to Skier:
>Т.е. поскольку ссылки не считаются интерфейс в этом случае
>не освободится ?
Понятия "освобождения" для интерфейсов не существует. Есть только понятие вызова Release. Что с этим делать - решает экземпляр. В случае с потомками TComponent по-умолчанию ничего не происходит, в чем TComponent абсолютно прав. Еще раз повторяю, временем жизни в данном случае управляет не сам объект, а его владелец.
← →
Skier (2003-08-21 19:19) [18]
> Понятия "освобождения" для интерфейсов не существует.
см. [16] :)
Про владелеца совсем забыл.
Спасибо за разъяснения.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.09.04;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.009 c