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