Является ли передача сообщений в светской беседе и ObjectiveC такой же, как и вызов метода с типами значений (структурами) в аргументе? - PullRequest
2 голосов
/ 27 марта 2011

Согласно википедии разница между передачей сообщений и вызовом метода составляет «При передаче сообщений каждый из аргументов должен иметь достаточно доступной дополнительной памяти для копирования существующего аргумента в часть нового сообщения."в то время как при вызове метода передается только адрес аргументов.

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

Ответы [ 3 ]

10 голосов
/ 28 марта 2011

После фактического вызова функции разницы нет.Разница между передачей сообщений и вызовом метода заключается в связывании.Для таких языков, как c и c ++, вызовы функций связаны во время компиляции с компоновщиком (за исключением виртуальных функций, которые требуют некоторой поддержки во время выполнения).С языками, использующими систему обмена сообщениями, такими как target-c и smalltalk, вы не можете гарантировать, какие функции будут выполняться до времени выполнения.Среда выполнения определяет, реализует ли объект функцию, представленную в сообщении.Если он не реализует его, класс обычно либо пересылает сообщение другому объекту, либо выдает исключение.Однако, если класс реализует его, среда выполнения определяет адрес фактической функции и вызывает его точно так же, как c (помещая аргументы и адрес возврата в стек).

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

7 голосов
/ 28 марта 2011

Objective-C, вызывающий ABI, обычно (можно написать ваш собственный ABI, если вы хотите) на 100% чистый C ABI; параметры и возвращаемые значения обрабатываются точно так же, как и на обычном сайте вызова C.

Единственное ключевое отличие состоит в том, что сайт вызовов Objective C всегда компилируется как вариант objc_msgSend(), а первые два параметра всегда являются целевым объектом (self) и вызываемым селектором (_cmd) ). Это то, что обеспечивает динамическую диспетчеризацию - возможность переопределять методы во время выполнения и т. П. - что делает Objective-C значительно отличным от C ++ (или аналогичным).

Для того, чтобы узнать о objc_msgSend() больше, чем вы когда-либо могли бы знать (вне команды времени выполнения и компилятора), я написал серию из 4 частей, в которой обзор по инструкции objc_msgSend().

3 голосов
/ 28 марта 2011

На странице, на которую вы ссылаетесь, говорится об удаленной передаче сообщений, например, SOAP или CORBA.Это действительно не имеет большого отношения (если вообще что-либо) к передаче сообщений Objective-C.(Да, статья в Википедии о Objective-C ссылается на нее - этой ссылки действительно не должно быть.)

Разница между отправкой сообщения и вызовом метода заключается в том, что первое является очень динамичным.Сопоставление имени сообщения с функцией, которая его обрабатывает, выполняется во время выполнения, тогда как вызов метода привязан к функции во время компиляции.

Это допускает тип динамического программирования, который невозможнолегко сделать в C ++.Например, среда выполнения Objective C будет искать -forwardInvocation: и вызывать его, если объект не отвечает напрямую на указанное сообщение.Это позволяет классу, такому как NSProxy, который может выступать в качестве «подставки» для любого другого класса, без необходимости знать все детали класса, для которого он является прокси.

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

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

Редактировать: Кстати, после того, как функция, обрабатывающая данное сообщение, разрешена, механизм вызова этой функции - то есть построение стекового фрейма для передачи аргументов - становится точно таким же, как если быпривязка имени к функции была сделана во время компиляции.Представление о том, что аргументы передаются по-разному, является просто красной селедкой, введенной в не по теме статьей в Википедии.

...