У меня есть базовый класс, который добавляет некоторые функциональные возможности к ряду производных классов в моем приложении.
Это предложение должно заставить вас переосмыслить свой дизайн. Базовый класс никогда не должен ничего делать с производными классами. Он должен не знать своих подклассов. (Несмотря на классовые кластеры. Это отдельный подход к проектированию, требующий, чтобы суперкласс был осведомлен о построении, что делает его шаблоном Factory, что хорошо.)
Одна из этих функций используется только некоторыми подклассами.
Это явный признак ошибки "Квадрат / Прямоугольник". В ООП (забудьте ObjC, это просто теория CS), квадрат не является прямоугольником . Вы должны убедиться, что ваши типы соответствуют принципу замещения Лискова. Опять же, это не имеет никакого отношения к какому-либо конкретному языку; это верно для всего дизайна ООП. Это может показаться очень «теоретическим», но оно серьезно испортит вашу реализацию, если вы выйдете из строя LSP, и вы будете преследовать тонкие ошибки гораздо дольше, чем вам нравится.
Шаблон, который вам, вероятно, нужен здесь, это Decorator, а не подклассы. Если у вас есть некоторые специальные функции, которые существуют в некоторых классах, вы хотите инкапсулировать эти функции в отдельный объект и присоединить его к подклассам, где это имеет смысл. Другим возможным шаблоном является Стратегия (которая обычно реализуется как «делегат» в ObjC, что является другим способом мышления о Decorator). Дело в том, что вам не нужна логика в суперклассе, которая применима только к некоторым подклассам. Вы хотите поместить эту логику в то, что существует только в соответствующих подклассах.
Если вам все это не поможет, тогда я настоятельно рекомендую простую функцию (BOOL)
для всего, что анализирует реализации метода. Этот способ хрупок, потому что он опирается на все более глубокие детали реализации. respondsToSelector:
определенно лучше, чем тестирование instanceMethodForSelector:
.