Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.09.04;
Скачать: CL | DM;

Вниз

Интерфейсы   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.018 c
9-10538
AndrewK
2002-09-26 12:47
2003.09.04
Как проверить коллизии?


1-10775
pvb87
2003-08-23 19:03
2003.09.04
Linux


3-10631
Lamer_of_Delphi
2003-08-13 09:38
2003.09.04
Запрос не выполняется!!!


14-10948
Klavishnik
2003-08-16 14:19
2003.09.04
Можно программно отключить


1-10795
Maks
2003-08-25 13:02
2003.09.04
Масштаб Image