Обнаружить подклассы данного класса в Obj-C - PullRequest
9 голосов
/ 28 ноября 2009

Есть ли способ обнаружить во время выполнения, какие подклассы существуют для данного класса?

Редактировать: Из ответов на этот вопрос я думаю, что мне нужно еще немного уточнить, что я пытаюсь сделать. Я знаю, что это не распространенная практика в Какао, и что это может сопровождаться некоторыми оговорками.

Я пишу парсер с использованием шаблона динамического создания. (См. Книгу «Модели проектирования какао» Бака и Яктмана, глава 5.) По сути, экземпляр синтаксического анализатора обрабатывает стек и создает экземпляры объектов, которые знают, как выполнять определенные вычисления.

Если я могу получить все подклассы класса MYCommand, я могу, например, предоставить пользователю список доступных команд. Кроме того, в примере из главы 5 синтаксический анализатор имеет словарь подстановки, поэтому можно использовать такие операторы, как +, -, * и /. (Они сопоставлены с MYAddCommand и т. Д.) Мне показалось, что эта информация относится к подклассу MyCommand, а не к экземпляру синтаксического анализатора, поскольку она как бы побеждает идею динамического создания.

Ответы [ 5 ]

19 голосов
/ 28 ноября 2009

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

Вы можете использовать objc_getClassList(), чтобы получить список Class объектов, зарегистрированных во время выполнения. Затем вы можете перебрать этот массив и вызвать [NSObject superclass] для этих Class объектов, чтобы получить их суперкласс 'Class объект. Если по какой-то причине ваши классы не используют NSObject в качестве корневого класса, вы можете использовать class_getSuperclass().

Я должен также упомянуть, что вы могли бы неправильно думать о дизайне вашего приложения, если считаете, что необходимо сделать такое открытие. Скорее всего, существует другой, более традиционный способ сделать то, что вы пытаетесь выполнить, который не включает в себя самоанализ в среде выполнения Objective C.

13 голосов
/ 28 ноября 2009

Вместо того, чтобы пытаться автоматически зарегистрировать все подклассы MYCommand, почему бы не разбить проблему на две части?

Во-первых, предоставьте API для регистрации класса, что-то вроде +[MYCommand registerClass:].

Затем создайте код в MYCommand, который означает, что любые подклассы будут автоматически регистрироваться. Что-то вроде:

@implementation MYCommand
+ (void)load
{
    [MYCommand registerClass:self];
}
@end
4 голосов
/ 28 ноября 2009

Марк и Бум бьют по деньгам. Обычно это не очень хорошая идея.

Тем не менее, у нас есть код в нашей вики CocoaHeads, который делает это: http://cocoaheads.byu.edu/wiki/getting-all-subclasses

3 голосов
/ 12 января 2010

Другой подход был только что опубликован Мэттом Галлахером на его блоге .

0 голосов
/ 29 ноября 2009

В моем проекте браузера времени выполнения есть код здесь , который включает метод -subclassNamesForClass: Смотрите RuntimeReporter.[hm] файлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...