Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
3-10634
Avreliy
2003-08-12 18:13
2003.09.04
Левое внешнее объединение 2х хранимых процедур


1-10730
Groove
2003-08-20 12:24
2003.09.04
У меня есть два вопроса


14-10904
KSergey
2003-08-18 12:35
2003.09.04
Про возможность


9-10534
Jedi Knight
2002-10-06 21:06
2003.09.04
Автомат в GlScene


3-10656
valmont
2003-08-12 06:04
2003.09.04
работы без BDE





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский