Ответ ... ну ... простой. Фактически, простота и последовательность.
Objective-C является чисто динамическим в момент отправки метода. В частности, отправка каждого метода проходит через ту же точку разрешения динамического метода, что и отправка любого другого метода. Во время выполнения каждая реализация метода имеет одно и то же представление, и все API, предоставляемые средой выполнения Objective-C, которые работают с методами и селекторами, работают одинаково для всех методов.
Как многие ответили (как здесь, так и в других вопросах), поддерживаются частные методы времени компиляции; если класс не объявляет метод в своем общедоступном интерфейсе, то этот метод также может не существовать в отношении вашего кода. Другими словами, вы можете достичь всех желаемых комбинаций видимости во время компиляции, правильно организовав свой проект.
Дублирование одной и той же функциональности во время выполнения не дает особых преимуществ. Это добавило бы огромной сложности и накладных расходов. И даже при всей этой сложности это все равно не помешает всем, кроме самых случайных разработчиков, выполнять ваши якобы «частные» методы.
РЕДАКТИРОВАТЬ: Одно из предположений, которое я заметил, заключается в том, что личные сообщения должны проходить через среду выполнения, что приводит к потенциально большим накладным расходам. Это абсолютно правда?
Да, это так. Нет причин предполагать, что разработчик класса не захочет использовать весь набор функций Objective-C в реализации, а это означает, что должна происходить динамическая отправка. Однако нет особой причины, по которой частные методы не могут быть отправлены специальным вариантом objc_msgSend()
, поскольку компилятор будет знать, что они были частными; то есть это может быть достигнуто путем добавления в Class
структуру таблицы методов, предназначенных только для частного использования .
Не было бы возможности частному методу сократить эту проверку или пропустить время выполнения?
Он не мог пропустить среду выполнения, но среда выполнения не обязательно должна была бы выполнять какие-либо проверки частных методов.
Тем не менее, нет причин, по которым третья сторона не могла бы преднамеренно вызвать objc_msgSendPrivate()
объект вне реализации этого объекта, и некоторые вещи (например, KVO) должны были бы это сделать. По сути, это было бы просто соглашение и на практике немного лучше, чем префикс селекторов частных методов или не упоминать их в заголовке интерфейса.
Однако это подорвало бы чистую динамическую природу языка. Отправка каждого метода больше не будет проходить через идентичный механизм отправки. Вместо этого вы окажетесь в ситуации, когда большинство методов ведут себя одинаково, а небольшая горстка - просто разные.
Это выходит за рамки среды выполнения, поскольку в Какао есть много механизмов, построенных на основе последовательного динамизма Objective-C. Например, и кодирование ключевого значения, и наблюдение ключевого значения должны быть либо очень сильно изменены для поддержки частных методов - скорее всего, путем создания уязвимой лазейки - либо частные методы будут несовместимы.