8.10.2 Обработчик переадресации ¶
GNU Objective-C runtime предоставляет обработчик, называемый __objc_msg_forward2, который вызывается objc_msg_lookup(), когда он не может найти реализацию метода в таблицах runtime и после неудачной попытки вызова +resolveInstanceMethod: и +resolveClassMethod: для динамической регистрации метода.
Для настройки обработчика вы устанавливаете глобальную переменную __objc_msg_forward2 в функцию с теми же аргументами и типом возвращаемого значения, что и у objc_msg_lookup(). Когда objc_msg_lookup() не может найти реализацию метода, он вызывает предоставленную вами функцию обработчика, чтобы получить реализацию метода для возврата. Таким образом, на практике __objc_msg_forward2 позволяет расширить objc_msg_lookup(), добавив некоторый пользовательский код, который вызывается для дальнейшего поиска, когда стандартная реализация метода не может быть найдена с помощью обычного поиска.
Этот обработчик обычно предназначен для библиотек «Foundation», таких как GNUstep Base, которые используют его для реализации своего API переадресации методов высокого уровня, как правило, на основе метода forwardInvocation:. Поэтому, если вы не реализуете собственную библиотеку «Foundation», вам не следует устанавливать этот обработчик.
В типичной реализации переадресации функция обработчика __objc_msg_forward2 определяет аргументы и тип возвращаемого значения метода, который ищется, а затем создаёт функцию, принимающую эти аргументы и имеющую этот тип возвращаемого значения, и возвращает её вызывающей стороне. Создание этой функции нетривиально и обычно выполняется с помощью специализированной библиотеки, например, libffi.
Таким образом созданная реализация метода переадресации возвращается objc_msg_lookup() и выполняется как обычная реализация метода. При вызове реализации метода переадресации обычно ожидается, что все аргументы будут упакованы в какой-то объект (как правило, в NSInvocation в библиотеке «Foundation»), и переданы программисту (forwardInvocation:), которому разрешается манипулировать вызовом метода с помощью API высокого уровня, предоставленного библиотекой «Foundation». Например, программист может захотеть изучить аргументы вызова метода, его имя и потенциально изменить их перед переадресацией вызова метода одному или нескольким локальным объектам (performInvocation:) или даже удалённым объектам (используя распределённые объекты или какой-либо другой механизм). После завершения всего этого значение возврата передаётся обратно и должно быть правильно возвращено исходной вызывающей стороне.
Обратите внимание, что GNU Objective-C runtime в настоящее время не поддерживает переадресацию методов или вызовы методов, кроме обработчика __objc_msg_forward2.
Если обработчик переадресации не существует или возвращает NULL, runtime в настоящее время пытается выполнить переадресацию с помощью более старого, устаревшего API, и если это не удаётся, программа завершается аварийно. В будущих версиях GNU Objective-C runtime runtime немедленно завершит работу.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-10.5.0/gcc/Forwarding-hook.html