Objective-C Найти все инициализации (методы конструктора)

используя "Method * class_copyMethodList(Class cls, unsigned int *outCount)" позволяет получить список всех методов, существующих в классе Objective-C.

Я хотел бы знать, как узнать, какие из этих методов являются конструкторами, когда я пишу контейнер IOC. Я хотел бы определить конструкторы и их типы параметров.


person Aran Mulholland    schedule 07.08.2011    source источник


Ответы (2)


Я хотел бы знать, как узнать, какие из этих методов являются конструкторами, когда я пишу контейнер IOC. Я хотел бы определить конструкторы и их типы параметров.

Короче говоря, вы не можете. Или, по крайней мере, вы обнаружите, что на этом пути лежит безумие.

Во-первых, в Objective-C нет конструкторов. У него есть инициализаторы, иногда много, и — для правильно написанного класса — только один из них является назначенным инициализатором. Невозможно идентифицировать назначенный инициализатор во время компиляции или во время выполнения.

Как мне использовать это с методом * и без экземпляра члена класса?

Вы не знаете. Сначала вы выделяете экземпляр класса, затем инициализируете экземпляр.

В целом, этот уровень абстракции просто не реализован в Objective-C за пределами академических исследований. Это можно сделать, но обычно этого избегают из-за хрупкости результирующего решения и комка адского кода, который пытается динамически поддерживать лежащий в основе C ABI (посмотрите исходный код на libffi).

Если вы хотите пойти по этому пути, то вам гораздо лучше либо определить собственный абстрактный класс, подклассом которого будут все ваши контейнеры, который может обеспечить логику привязки к классу, стоящему за ним.

Или используйте протоколы; то есть класс может реализовать протокол IOCBean, и одним из методов будет initIOCGoop, который является назначенным инициализатором goo.

Выполнение этого в общем для всех классов будет изобиловать хрупкостью, особыми случаями и потребует гигантского беспорядка кода, который будет трудно поддерживать с течением времени.

person bbum    schedule 07.08.2011
comment
ну вот и все... :( Я думаю, что лучше всего использовать ваше второе решение (протоколы). Я немного разочарован тем, что этот шаблон на самом деле не поддерживается функциями языка. - person Aran Mulholland; 08.08.2011
comment
По моему опыту, IOC не очень хорошо используется в Objective-C. Большинство шаблонов на основе контейнеров/бинов, которые я когда-либо использовал, просто включают в себя гораздо больше стандартного кода, чтобы сделать то же самое, что можно сделать с очень небольшим количеством кода в Objective-C. Не поймите меня неправильно; это может быть мощной штукой, но только с IDE, которая полностью поддерживает шаблон и скрывает повторяющийся мусор. (Я хотел бы узнать больше о том, что именно вы хотите сделать.) - person bbum; 08.08.2011

Вы можете получить сигнатуру метода, используя следующий метод:

методSignatureForSelector:

Из документации:

Объект NSMethodSignature записывает информацию о типе для аргументов и возвращаемого значения метода. Он используется для пересылки сообщений, на которые принимающий объект не отвечает, особенно в случае распределенных объектов. Обычно вы создаете объект NSMethodSignature, используя метод экземпляра methodSignatureForSelector: NSObject (в Mac OS X v10.5 и более поздних версиях вы также можете использовать сигнатуруWithObjCTypes:). Затем он используется для создания объекта NSInvocation, который передается в качестве аргумента в сообщение forwardInvocation: для отправки вызова любому другому объекту, который может обработать сообщение. По умолчанию NSObject вызывает метод doNotRecognizeSelector:, который вызывает исключение. Для распределенных объектов объект NSInvocation кодируется с использованием информации в объекте NSMethodSignature и отправляется реальному объекту, представленному получателем сообщения.

person ennuikiller    schedule 07.08.2011
comment
Но говорит ли это ему, какие из них являются инициализаторами (или, как он их называет, конструкторами)? AFAICT, инициализаторы - это простые методы Obj-C. - person Rudy Velthuis; 08.08.2011
comment
@Rudy - это то, что я подозреваю, однако они возвращают идентификатор. Я полагаю, вы могли бы использовать это плюс тот факт, что они начинаются со слова init и просто называют их конструкторами, но это кажется очень хакерским решением. Можно ли с уверенностью предположить, что эти методы единственные, которые вызывают [NSObject init] где-то вверх по цепочке наследования? Интересно, можно ли использовать эту информацию. - person Aran Mulholland; 08.08.2011
comment
IOW, он должен полагаться на соглашение об именах. Если кто-то решит использовать другое имя (например, createWithBla:), оно не будет узнаваемо как таковое. - person Rudy Velthuis; 08.08.2011
comment
@Aran: не забывайте, что есть также [X new], который является ярлыком для [[X alloc] init] (тот, который кажется рассмотренным, но его все еще можно использовать). - person Rudy Velthuis; 08.08.2011
comment
Как мне использовать это с методом * и без экземпляра члена класса? - person Aran Mulholland; 08.08.2011
comment
Обратите внимание, что методы init* не обязаны возвращать (id) (и некоторые из них этого не требуют). Обратите внимание, что вам, вероятно, потребуется написать API для обработки каждого типа аргумента, не являющегося объектом, при настройке оболочки NSInvocation. - person bbum; 08.08.2011