Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Механизм подсчета ссылок в интерфейсах

Механизм вызова виртуального метода | Абстрактный виртуальный метод | Методы обработки сообщений | Понятие ссылки на метод объекта | Понятие события | Ошибки и исключительные ситуации | Классы исключительных ситуаций | В тот момент, когда управление передается на Except, в программе считается, что ошибка обработана. | Для возврата по try используется стек вызова процедур. | Приемы надежного программирования |


Читайте также:
  1. http://bither.livejournal.com/325211.html ликбез: майдан, Украина, ссылки (копии ссылок), бандеровцы и прочее. Жестко и нелицеприятно
  2. IV этап(с середины XX в. по настоящее время)– психология как наука, изучающая факты, закономерности и механизмы психики
  3. Агроөнеркәсіптік кешенді мемлекеттік реттеудің бағыты, әдістері және нақты механизмдері
  4. Административный механизм управления энергосбережением
  5. Анатомо-физиологическое обоснование массажа, механизм его действия на организм человека
  6. Аппаратные средства поддержки многозадачной работы микропроцессора. Структура таблици состояния задач. Алгоритмы и механизмы переключения задач
  7. Барьерные методы контрацепции. Механизм действия. Показания и противопоказания, побочные действия. Способ применения.

Механизм подсчета ссылок на объект предназначен для автоматического уничтожения неиспользуемых объектов. Неиспользуемым считается объект, на который не ссылается ни одна интерфейсная переменная. Подсчет ссылок на объект обеспечивают методы _ AddRef и _ Release интерфейса IInterface. При копировании значения интерфейсной переменной вызывается метод _ AddRef, а при уничтожении интерфейсной переменной – метод _ Release. Вызовы этих методов генерируются компилятором автоматически.

 

Var

Intf, Copy: IInterface;

Begin

Copy:= Intf; // Copy._Release; Intf._AddRef;

Intf:= nil; // Intf._Release;

end; // Copy._Release

Стандартная реализация методов _ AddRef и _ Release находится в классе TInterfacedObject.

Type

TInterfacedObject = class(TObject, IInterface)

...

FRefCount: Integer; // Счетчик ссылок

function_AddRef: Integer; stdcall;

function_Release: Integer; stdcall;

...

End;

function TInterfacedObject._AddRef: Integer;

Begin

Result:= InterlockedIncrement(FRefCount); // Увеличение счетчика ссылок

End;

function TInterfacedObject._Release: Integer;

Begin

Result:= InterlockedDecrement(FRefCount); // Уменьшение счетчика ссылок

If Result = 0 then // Если ссылок больше нет, то

Destroy; // уничтожение объекта

End;

Функции InterlockedIncrement и InterlockedDecrement просто увеличивают значение целочисленной переменной на единицу. В отличие от обычного оператора сложения, они обеспечивают атомарное изменение значения переменной, что очень важно для правильной работы многопоточных программ.

Var

Obj: TDelimitedReader;

Intf, Copy: ITextReader;

Begin

Obj:= TDelimitedReader.Create('MyData.del', ';');

Intf:= Obj; // Obj._AddRef -> Obj.FRefCount = 1

Copy:= Intf; // Obj._AddRef -> Obj.FRefCount = 2

...

Intf:= nil; // Obj._Release -> Obj.FRefCount = 1

Copy:= nil; // Obj._Release -> Obj.FRefCount = 0 -> Obj.Destroy

Obj.Free; // Ошибка! Объект уже уничтожен и переменная Obj указывает в никуда

End;

Обратите внимание, что объектные переменные не учитываются при подсчете ссылок. Поэтому мы настоятельно рекомендуем избегать смешивания интерфейсных и объектных переменных. Если вы планируете использовать объект через интерфейс, то лучше всего результат работы конструктора сразу присвоить интерфейсной переменной:

Var

Intf: ITextReader;

Begin

Intf:= TDelimitedReader.Create('MyData.del', ';'); // FRefCount = 1

...

Intf:= nil; // FRefCount = 0 -> Destroy

End;

 

Если интерфейс является входным параметром подпрограммы, то при вызове подпрограммы

создается копия интерфейсной переменной с вызовом метода _ AddRef:

procedure LoadItems(R: ITextReader);

 

Var

Reader: ITextReader;

Begin

LoadItems(Reader); // Создается копия переменной Reader и вызывается


Дата добавления: 2015-11-16; просмотров: 58 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Описание интерфейса| Reader._AddRef

mybiblioteka.su - 2015-2024 год. (0.007 сек.)