Объективный механизм с отправкой сообщений


Я просто смотрю, чтобы поиграть с Objective C (писать игрушечные приложения для iPhone), и мне любопытно, какой механизм используется для отправки сообщений. У меня есть хорошее понимание того, как обычно реализуются виртуальные функции в C++ и каковы затраты по отношению к статическому или невиртуальному вызову метода, но у меня нет фона с Obj-C, чтобы знать, как отправляются сообщения. Просматривая вокруг я нашел этой loose benchmark и он упоминает IMP кэшированные сообщения быть быстрее, чем вызовы виртуальных функций, которые, в свою очередь, быстрее, чем стандартное сообщение отправить.

Я не пытаюсь ничего оптимизировать, просто получить более глубокое понимание того, как именно отправляются сообщения.

  • как отправляются сообщения Obj-C?
  • как указатели метода экземпляра кэшируются и можете ли вы (в целом) сказать, прочитав код, если сообщение будет кэшироваться?
  • являются ли методы класса по существу такими же, как и C функция (или статический метод класса В C++), или есть что-то еще для них?

Я знаю, что некоторые из этих вопросов может быть зависящим от реализации, но есть только одна реализация, которая действительно имеет значение.

2 59

2 ответа:

как отправляются сообщения Obj-C?

сообщения Objective-C отправляются с помощью . Показано в Apple docs, функция принимает не менее 2 аргументов:

  1. принимающий объект
  2. селектор сообщения
  3. [список переменных аргументов для отправляемого сообщения.]

экземпляры класса имеют isa указатель, который является указатель на объект класса. Селекторы методов в каждом объекте хранятся в "таблице" в объекте класса, а следует isa указатель на объект класса, чтобы найти в этой таблице, и проверяет, является ли метод в таблице для класса. Если он не может найти его, он ищет метод в таблице суперкласса класса. Если он не найден, он продолжает подниматься по дереву объектов, пока не найдет метод или не доберется до корневого объекта (NSObject). В этот момент, исключение.

как указатели метода экземпляра кэшируются и вы можете (в целом) сказать, прочитав код, если сообщение будет кэшироваться?

из руководства Apple Objective-C runtime guide on сообщения:

чтобы ускорить процесс обмена сообщениями, система выполнения кэширует селекторы и адреса методов по мере их использования. Есть отдельный кэш для каждого класса, и он может содержать селекторы для унаследованные методы, а также для методов, определенных в классе. Перед поиском в таблицах диспетчеризации процедура обмена сообщениями сначала проверяет кэш класса принимающего объекта (исходя из теории, что метод, который использовался один раз, может быть использован снова). Если селектор метода находится в кэше, обмен сообщениями происходит лишь немного медленнее, чем вызов функции. Как только программа работает достаточно долго, чтобы "разогреть" свои кэши, почти все сообщения, которые она отправляет, находят кэшированный метод. Кэши растут динамически для размещения новых сообщений по мере выполнения программы.

как указано, кэширование начинает происходить после запуска программы, и после того, как программа работает достаточно долго, большинство вызовов метода будет выполняться через кэшированный метод. Как он также говорит, кэширование происходит по мере использования методов, поэтому сообщение кэшируется только тогда, когда оно используется.

являются ли методы класса по существу такими же, как функция C (или статический метод класса В C++), или есть что-то больше к ним?

объекты класса обрабатывают метод отправки аналогично экземплярам классов. Каждый объект класса имеет объект, который хранит свой собственный класс методы, в объекте под названием A metaclass. Объект класса имеет свой собственный isa указатель на свой объект метакласса, который в свою очередь имеет супер объекты метакласса, от которых он может наследовать объекты класса. Отправка метода в методы класса выглядит так:

  1. система диспетчеризации следует за объектом класса isa указатель на объект метакласса
  2. в таблице методов объекта metaclass выполняется поиск метода класса.
  3. если не найдено, поиск продолжается до суперкласса объекта метакласса, где поиск продолжается.
  4. этот процесс повторяется до тех пор, пока метод не будет найден или пока он не доберется до корневого метакласса, и не будет выдано исключение.

Я также написал инструкцию по инструкции для objc_msgSend () на x86_64 в моем блоге, если кто-то хочет погрузиться глубоко:

http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/