0

Вызов метода или отправка сообщения в Objective-C

14

В C или любом языке на основе ECMAScript вы «вызываете публичный метод или функцию» у объекта. Однако в документации по Objective-C нет упоминания о вызовах публичных методов, а только о передаче сообщений.

Есть ли что-то неправильное в том, чтобы считать, что когда вы «отправляете сообщение» в Objective-C, вы на самом деле «вызываете публичный метод у объекта»?

3 ответ(ов)

0

Теоретически они разные.

Практически — не так уж и сильно.

Разница заключается в том, что в Objective-C объекты могут не реагировать на сообщения или перенаправлять их другим объектам и так далее. В языках, таких как C, вызовы функций по сути представляют собой переход к определенному участку памяти и выполнение кода. Здесь нет динамического поведения.

Однако в стандартных случаях, когда вы отправляете сообщение объекту, метод, соответствующий этому сообщению, обычно будет вызван. Таким образом, примерно в 99% случаев отправка сообщения приводит к вызову метода. Поэтому мы часто говорим "вызвать метод", когда на самом деле имеем в виду "отправить сообщение". Таким образом, на практике они почти всегда одно и то же, но не обязательно.

Недавно я размышлял на эту тему и написал об этом в блоге: ссылка

Редактирование

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

(К слову, лично мне больше нравится говорить "вызывать метод у объекта".)

0

Из-за динамической отправки сообщений в Objective-C, процесс отправки сообщения отличается от вызова функции на C или метода на C++ (хотя в конечном итоге будет вызвана функция C). Сообщения отправляются через селекторы объекту-получателю, который либо отвечает на сообщение, вызывая IMP (указатель на функцию C), либо перенаправляет сообщение своему суперклассу. Если ни один класс в цепочке наследования не отвечает на сообщение, генерируется исключение. Также возможно перехватить сообщение и перенаправить его в совершенно другой класс (именно это делают подклассы NSProxy).

При использовании Objective-C нет значительной разницы между отправкой сообщений и вызовом методов в стиле C++, но есть несколько практических особенностей системы передачи сообщений, о которых мне известно:

  1. Поскольку обработка сообщений происходит во время выполнения, а не на этапе компиляции, нет способа на этапе компиляции узнать, отвечает ли класс на конкретное сообщение. Поэтому обычно вы получаете предупреждения компилятора вместо ошибок, если, например, вы ошиблись в написании метода.
  2. Вы можете безопасно отправить любое сообщение nil, что позволяет использовать идиомы типа [foo release] без беспокойства о проверке на NULL.
  3. Как упоминает @CrazyJugglerDrummer, диспетчеризация сообщений позволяет вам отправлять сообщения множеству объектов одновременно, не беспокоясь о том, отреагируют ли они на них. Это позволяет использовать неформальные протоколы и отправлять сообщения всем объектам в контейнере.
  4. Я не на 100% уверен в этом, но думаю, что категории (добавление методов к уже существующим классам) стали возможны благодаря динамической диспетчеризации сообщений.
  5. Отправка сообщений позволяет производить перенаправление сообщений (например, с помощью подклассов NSProxy).
  6. Отправка сообщений также позволяет заниматься интересными низкоуровневыми трюками, такими как свопинг методов (обмен реализацией методов во время выполнения).
0

В языке C при вызове функции компилятор заменяет селектор вызовом функции, и выполнение переходит к данной функции.

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

В результате, Objective-C позволяет загружать и связывать новые классы и категории во время работы, а также применять такие техники, как свизлинг, категории, прокси-объекты и другие. Ничего подобного невозможно в C.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь