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-5.5.0/gcc/Forwarding-hook.html