La respuesta es ... bueno ... simple. Simplicidad y consistencia, de hecho.
Objective-C es puramente dinámico en el momento del envío del método. En particular, cada envío de método pasa por el mismo punto de resolución de método dinámico que cualquier otro envío de método. En tiempo de ejecución, cada implementación de método tiene exactamente la misma exposición y todas las API proporcionadas por el tiempo de ejecución de Objective-C que funcionan con métodos y selectores funcionan de la misma manera en todos los métodos.
Como muchos han respondido (tanto aquí como en otras preguntas), se admiten métodos privados en tiempo de compilación; si una clase no declara un método en su interfaz disponible públicamente, entonces ese método podría no existir en lo que respecta a su código. En otras palabras, puede lograr todas las diversas combinaciones de visibilidad deseadas en el momento de la compilación organizando su proyecto adecuadamente.
Hay pocos beneficios al duplicar la misma funcionalidad en el tiempo de ejecución. Agregaría una enorme cantidad de complejidad y sobrecarga. E incluso con toda esa complejidad, todavía no evitaría que todos, excepto el desarrollador más informal, ejecuten sus métodos supuestamente "privados".
EDITAR: Una de las suposiciones que he notado es que los mensajes privados tendrían que pasar por el tiempo de ejecución, lo que generaría una sobrecarga potencialmente grande. ¿Es esto absolutamente cierto?
Sí lo es. No hay razón para suponer que el implementador de una clase no quiera usar todo el conjunto de características de Objective-C en la implementación, y eso significa que debe ocurrir un despacho dinámico. Sin embargo , no hay una razón particular por la cual los métodos privados no puedan ser enviados por una variante especial de objc_msgSend()
, ya que el compilador sabría que son privados; es decir, esto podría lograrse agregando una tabla de método solo privado a la Class
estructura.
¿No habría forma de que un método privado haga un cortocircuito en esta verificación o se salte el tiempo de ejecución?
No podía omitir el tiempo de ejecución, pero el tiempo de ejecución no necesariamente tendría que hacer ninguna comprobación de métodos privados.
Dicho esto, no hay razón para que un tercero no pueda invocar deliberadamente objc_msgSendPrivate()
un objeto, fuera de la implementación de ese objeto, y algunas cosas (KVO, por ejemplo) tendrían que hacer eso. En efecto, sería una convención y un poco mejor en la práctica que prefijar los selectores de métodos privados o no mencionarlos en el encabezado de la interfaz.
Sin embargo, hacerlo socavaría la naturaleza puramente dinámica del lenguaje. Ya no todos los envíos de métodos pasarían por un mecanismo de envío idéntico. En cambio, quedaría en una situación en la que la mayoría de los métodos se comportan de una manera y un pequeño puñado son simplemente diferentes.
Esto se extiende más allá del tiempo de ejecución ya que hay muchos mecanismos en Cocoa construidos sobre el dinamismo constante de Objective-C. Por ejemplo, tanto la codificación del valor clave como la observación del valor clave tendrían que modificarse en gran medida para admitir métodos privados, muy probablemente creando una escapatoria explotable, o los métodos privados serían incompatibles.