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