Не могли бы вы подробнее рассказать об этом универсальном прокси и о том, на что ему нужно пересылать?
Если вашему прокси-серверу нужно пересылать каждое сообщение только одной цели, он может сделать это в своем -forwardingTargetForSelector:
во время выполнения. Если нет (например, вам нужно перенаправить на несколько целей или выполнить другие сложные манипуляции), вам нужно реализовать -forwardInvocation:
, чтобы справиться с этим. Использование -forwardInvocation:
для обработки вызовов требует, чтобы вы реализовали -messageSignatureForSelector:
, потому что ему необходимо получить сигнатуру метода, чтобы иметь возможность создать вызов. (Даже если вы пересылаете его другому объекту, этот объект также должен либо реализовать метод напрямую, либо добавить метод в ответ на +resolveInstanceMethod:
, либо обработать его с помощью -forwardInvocation:
, и все это требует, чтобы он также имел подпись.)
Сигнатура метода кодирует типы аргументов и тип возвращаемого значения. Причина, по которой эта информация необходима для вызова, заключается в том, что когда эти аргументы передаются, они размещаются во время компиляции (возможно, последовательно) в памяти в соответствии с их типами в объявлении. Большой структурный параметр займет больше места, чем целочисленный параметр. Double также, вероятно, больше, чем int. Вызов должен хранить все эти аргументы и позволять вам получать к ним доступ или изменять их по индексу. Невозможно выяснить, как располагаются аргументы во время выполнения, если вы не знаете типы (или, по крайней мере, размеры типов).
Кроме того, механизм передачи сообщений для методов, возвращающих структуры (они вызывают objc_msgSend_stret
), отличается от других методов (они вызывают objc_msgSend
) (а на некоторых платформах методы, возвращающие двойные числа, используют objc_msgSend_fpret
). В первом случае структура не возвращается напрямую, но место для записи передается как дополнительный аргумент-указатель в качестве выходного параметра. Таким образом, знание типа возвращаемого значения также имеет решающее значение для обработки вызова и возвращаемого значения при вызове.
Даже если вы перенаправляете вызов какому-то другому объекту, в конечном итоге этот объект (или какой-то объект, который он перенаправляет вниз по линии) должен каким-то образом знать сигнатуру метода. Так почему бы не запросить у этого объекта сигнатуру селектора, когда она вам понадобится?
Не существует «безопасной» подписи, которая будет работать для всех вещей, потому что разные типы имеют разные размеры.
person
newacct
schedule
11.05.2012