Что происходит при вызове метода? Где аргументы выдвинуты? - PullRequest
3 голосов
/ 03 августа 2011

Когда вы вызываете метод, например, [objectA message:arg1 argument:arg2], что происходит с аргументами?

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

Причина, по которой я спрашиваю, состоит в том, что когда вы получаете трассировку стека, вы получаете адрес функций или методов, которые были вызваны по порядку. Когда метод или функция возвращается, тот, кто вызвал его, все еще имеет ссылку на свои собственные аргументы. Так что я должен где-то ссылаться на arg1 и arg2. Следовательно, из трассировки стека и символов стека на устройстве iOS вы должны иметь возможность получить метод или функцию, которая вызвала любой другой метод или функцию, а также получить ее аргументы.

Как вы получили эти аргументы?

По этому другому вопросу: вызов метода цель C log , они показывают метод для получения NSMethodSignature метода и, используя его, вы можете получить номер и тип аргумента.

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

Любая помощь будет оценена.


ОБНОВЛЕНИЕ

2011-08-03

В ответ на комментарии "fakeAccount22" я хотел бы сделать это во время выполнения из приложения.

Мой вопрос в основном сводится к следующему: во время выполнения и в приложении как вы получаете доступ к стеку вызовов или указателю стека в Objective-C для устройства iOS? Отличается ли он для Mac OSX?

Ответы [ 2 ]

4 голосов
/ 03 августа 2011

Ключевым моментом здесь является то, что когда вы вызываете

[objectA message:arg1 argument:arg2]

Вы не вызываете метод , но отправляете сообщение . Зачем? Потому что в конце эта строка переводится компилятором в это:

objc_msgSend(objectA, "message:argument:", arg1, arg2)

Это все волшебство. Все остальное работает как в C. Здесь довольно хорошее объяснение 1012 *.

Вот почему все методы Objective C могут быть переведены на их C-аналог (ну, на самом деле они действительно переведены). Например. ваш пример выглядит так:

return_type method(id self, SEL _cmd, arg1_type arg1, arg2_type arg2) {
//implementation
}
2 голосов
/ 03 августа 2011

Помимо того, что написал Макс, имена и аргументы метода известны, потому что компилятор генерирует огромную нагрузку отладочной информации, сгенерированной из исходного кода, и отладчик может использовать ее для поиска имен методов, а также имен и значений их аргументы и т. д. Эта отладочная информация обычно не легко доступна, когда вы запускаете свой код без отладчика, хотя она должна быть как-то доступна, если вы знаете формат, в котором она хранится. Но учтите, что он может меняться с каждой новой компиляцией.

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

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

...