8.10.2 Крючок перенаправления
GNU Objective-C среда выполнения предоставляет крючок, называемый __objc_msg_forward2, который вызывается objc_msg_lookup(), когда она не может найти реализацию метода в таблицах среды выполнения и после попыток вызова +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 среда выполнения в настоящее время не поддерживает перенаправление методов или вызовы методов, кроме крючка __objc_msg_forward2.
Если крючок перенаправления не существует или возвращает NULL, среда выполнения в настоящее время пытается выполнить перенаправление с использованием более старого, устаревшего API, и если это не удаётся, прерывает выполнение программы. В будущих версиях GNU Objective-C среда выполнения будет немедленно прерываться.
Предыдущий: Динамическая регистрация методов, Вверх: Обмен сообщениями с GNU Objective-C средой выполнения [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/Forwarding-hook.html