Интернет магазин китайских планшетных компьютеров



Компьютеры - Objective-C - Как работает механизм сообщений

06 июля 2011


Оглавление:
1. Objective-C
2. Синтаксис языка
3. Создание новых классов
4. Как работает механизм сообщений
5. Протоколы
6. Обработка исключений
7. Создание и уничтожение объектов
8. Управление памятью
9. Категории
10. Class objects и Objective-C runtime
11. Разное



Компилятор переводит каждую посылку сообщения, то есть конструкцию вида в вызов функции objc_msgSend. Эта функция в качестве своего первого параметра принимает указатель на объект-получатель сообщения, в качестве второго параметра выступает т. н. селектор, служащий для идентификации посылаемого сообщения. Если в сообщении присутствуют аргументы, то они также передаются objc_msgSend как третий, четвёртый и т. д. параметры.

Каждый объект Objective-C содержит в себе атрибут isa — указатель на class object для данного объекта. class object автоматически создается компилятором и существует как один экземпляр, на который через isa ссылаются все экземпляры данного класса.

Каждый class object обязательно содержит в себе указатель на class object для родительского класса и dispatch table. Последняя представляет собой словарь, сопоставляющий селекторам сообщений фактические адреса реализующих их методов.

Таким образом, функция objc_msgSend ищет метод с данным селектором в dispatch table для данного объекта. Если его там нет, то поиск продолжается в dispatch table для его родительского класса и т. д.

Если метод находится, то осуществляется его вызов с передачей всех необходимых аргументов.

В противном случае объекту дается последний шанс обработать сообщение перед вызовом исключения — селектор сообщения вместе с параметрами «заворачивается» в специальный объект типа NSInvocation и объекту посылается сообщение forwardInvocation:, где в качестве параметра выступает объект класса NSInvocation.

Если объект поддерживает forwardInvocation:, то он может либо сам обработать посылаемое сообщение, либо переслать другому объекту для обработки:

- forwardInvocation:anInvocation
{
    if 
        ;
    else
       ..........
}

Для ускорения поиска сообщений по dispatch table используется кэширование, позволяющее заметно снизить затраты на пересылку сообщений. Также облегчает поиск метода по таблицам использование так называемых селекторов вместо обычных имен. Обычно селектор представляет собой 32-битовую величину, позволяющую однозначно идентифицировать метод.

Тип селектора обозначается как SEL и существует ряд функций и конструкций, позволяющих осуществлять преобразование имени в селектор и обратно.

Так для получения селектора сообщения непосредственно по имени служит конструкция @selector:

   SEL setWidth = @selector;
   SEL setPos   = @selector;

Для получения селектора по строке символов и перевода селектора в строку служат функции NSSelectorFromString и NSStringFromSelector:

   SEL        setWidth   = NSSelectorFromString ;
   NSString * methodName = NSStringFromSelector  ;

Мощная поддержка метаинформации в Objective-C позволяет прямо на этапе выполнения проверить поддерживает ли объект метод с данным селектором при помощи посылки ему сообщения respondsToSelector::

    if ] )
         ;

Довольно легко можно послать сообщение, соответствующее данному селектору, при помощи метода performSelector:, performSelector:withObject:, performSelector:withObject:withObject: и performSelector::withObject:withObject:withObject:.

    ;

Обратите внимание, что методы performSelector: всегда возвращают значение типа id.

Можно получить класс для данного объекта, послав ему сообщение class. Это сообщение возвращает класс в виде указателя на объект типа Class.

    Class    * cls     = ;
    NSString * clsName = NSStringFromClass ;

С другой стороны также можно легко получить соответствующий class object по имени класса:

    Class * cls = NSClassFromString ;

Каждый метод фактически представляет собой функцию с двумя невидимыми аргументами — self и _cmd.

Первый является аналогом this, то есть указывает на сам объект — получатель сообщения. Второй — содержит селектор данного метода.

Аргумент self может использоваться для посылки сообщений самому себе, как например в следующем методе:

-  area
{
   return  * ;
}

Однако кроме self есть ещё одна величина, которой могут посылаться сообщения — super. На самом деле super не является нормальной переменной — это всего лишь ещё одно обозначение для указателя на текущий объект. Но при посылке сообщения super поиск метода начинается не с dispatch table текущего объекта, а с dispatch table родительского объекта.

Таким образом, посылая сообщения super мы тем самым вызываем старые версии методов, переопределенные данным классом.

В языке Objective-C можно по селектору метода получить адрес реализующей его функции.

Такая функция отличается от описания метода только вставкой в начало списка аргументов двух дополнительных параметров — указателя на сам объект и селектора данного метода.

Послав объекту сообщение methodForSelector: мы получаем в ответ адрес реализующей этот метод функции.

typedef float ;
typedef void  ;
 
WidthFunc    widthFunc    =     ;
SetWidthFunc setWidthFunc =  ;
 
, 27.5f );

Это позволяет при необходимости многократного вызова одного и того же метода у заданного объекта полностью избежать всех расходов, связанных с пересылкой сообщений.



Просмотров: 10626


<<< Mission Control
Photo Booth >>>