Pregunta

Estoy aprendiendo Objective-C y tengo experiencia en C / C ++.

  • En C ++ orientado a objetos, siempre debe declarar su método antes de definirlo (implementarlo), incluso si se declara en la clase padre.

  • En el estilo de procedimiento C, IIRC, puede salirse con la simple definición de una función siempre que solo se invoque desde otra cosa en la misma unidad de compilación (es decir, el mismo archivo) que vino más adelante en el archivo (bueno, siempre que no lo declares en otro lugar con " extern ").

  • Ahora, en Objective-C, parece que solo necesita declarar selectores en el archivo de encabezado si van a ser utilizados por algo externo, y que puede inventar selectores en su archivo .m solo bien, y llámalos dentro del archivo .m. Además, parece que los métodos delegados o los métodos heredados nunca se (re) definen.

¿Estoy en el camino correcto? ¿Cuándo necesita definir un selector en Objective-C?

¿Fue útil?

Solución

Para los métodos Objective-C, la práctica general es poner los métodos que desea exponer en la sección @interface del archivo de encabezado para que otro código pueda incluir solo el .h y saber cómo interactuar con tu código `` Declaración diferida '' basada en pedidos funciona igual que las funciones en C & # 8212; no tiene que declarar un prototipo de método a menos que tenga una dependencia que no se puede resolver mediante un pedido, pero puede agregar prototipos de método dentro del @implementation si es necesario .

Entonces sí, estás en el camino correcto. No repita el prototipo del método para métodos heredados & # 8212; el compilador lo encuentra en el archivo de encabezado del padre. Los métodos de delegado pueden definirse como prototipos en una categoría (añadidos a una clase) e implementarse como se desee, pero el delegado no necesita proporcionar un prototipo de método, ya que ya está definido. (Todavía puede hacerlo si quiere claridad, etc.)

Como solo estás aprendiendo Objective-C, el resto de esta respuesta es mucho más detallada de lo que pediste. Usted ha sido advertido. ;-)


Cuando escribe estáticamente una variable (por ejemplo, MyClass * en lugar de id ) el compilador le avisará cuando intente llamar a un método que una clase no anuncia que implementa, lo haga o no. Si escribe dinámicamente la variable, el compilador no le impedirá llamar a lo que quiera, y solo obtendrá errores de tiempo de ejecución si llama a algo que no existe. En lo que respecta al lenguaje, puede llamar a cualquier método que implemente una clase sin errores en tiempo de ejecución & # 8212; no hay forma de restringir quién puede llamar a un método.

Personalmente, creo que esto es realmente algo bueno. Nos acostumbramos tanto a encapsular y proteger nuestro código de otro código que a veces tratamos a la persona que llama como un malvado desviado en lugar de un compañero de trabajo o cliente confiable. Creo que es bastante agradable codificar con una mentalidad de "tú haces tu trabajo y yo hago el mío". donde todos respetan los límites y se ocupan de lo suyo. Se podría decir que la "actitud" de Objective-C es de confianza comunitaria, más que de estricta aplicación. Por ejemplo, estoy feliz de ayudar a cualquiera que venga a mi escritorio, pero me molestaría mucho si alguien se metiera con mis cosas o moviera las cosas sin preguntar. El código bien diseñado no tiene que ser paranoico o sociópata, solo tiene que funcionar bien juntos. :-)

Dicho esto, hay muchos enfoques para estructurar sus interfaces, dependiendo del nivel de granularidad que desee / necesite al exponer las interfaces a los usuarios. Cualquier método que declares en el encabezado público es esencialmente un juego justo para que cualquiera lo use. Ocultar declaraciones de métodos es un poco como bloquear su automóvil o casa & # 8212; probablemente no mantendrá a todos fuera, pero (1) mantiene a la gente honesta honesta " al no tentarlos con algo con lo que no deberían meterse, y (2) cualquiera que entre seguramente sabrá que no se supone que deben hacerlo, y realmente no puede quejarse de las consecuencias negativas.

A continuación se presentan algunas convenciones que uso para nombrar archivos, y lo que incluye cada archivo & # 8212; comenzando desde un archivo .m en la parte inferior, cada archivo incluye el que está arriba. (El uso de una cadena estricta de inclusiones evitará cosas como advertencias de símbolos duplicados). Algunos de estos niveles solo se aplican a componentes reutilizables más grandes, como los marcos de Cocoa. Adáptelos de acuerdo a sus necesidades y use los nombres que más le convengan.

  • MyClass.h & # 8212; API pública (interfaz de programación de aplicaciones)
  • MyClass_Private.h & # 8212; SPI interno de la empresa (interfaz de programación del sistema)
  • MyClass_Internal.h & # 8212; Proyecto interno IPI (interfaz de programación interna)
  • MyClass.m & # 8212; Implementación, generalmente de todas las declaraciones API / SPI / IPI
  • MyClass_Foo.m & # 8212; Implementación adicional, como para categorías

API es para que todos lo usen, y es públicamente compatible (generalmente en Foo.framework / Headers ). SPI expone funcionalidades adicionales para clientes internos de su código, pero con el entendimiento de que el soporte puede ser limitado y la interfaz está sujeta a cambios (generalmente en Foo.framework / PrivateHeaders ). IPI consta de detalles específicos de la implementación que nunca deben usarse fuera del proyecto en sí, y estos encabezados no están incluidos en el marco. Cualquiera que elija usar llamadas SPI e IPI lo hace bajo su propio riesgo, y generalmente en detrimento de ellos cuando los cambios rompen su código. :-)

Otros consejos

Declarar los métodos en el archivo de encabezado solo detendrá las advertencias del compilador. Objective-C es un lenguaje dinámico, por lo que puede llamar a un método (enviar un mensaje) a un objeto independientemente de si ese método se declara externamente.

Además, si define un método en el archivo .m sobre cualquier código que lo llame (declaración diferida), eso no generará ninguna advertencia. Sin embargo, lo mismo se aplica, puede enviar un mensaje a un objeto sin que se declare.

Por supuesto, esto significa que no hay métodos privados en Objective-C. Se puede llamar a cualquier método que implemente una clase.

Preferencia personal. Si es un método público (es decir, uno utilizado externamente). declararlo en .h y definir en .m. Si desea limitar su visibilidad, o al menos indicar que es un método privado, use categorías / extensiones de clase en el. archivo m Aunque muchos códigos de ejemplo usan el método de declaración diferida.

Objective-C trata las funciones como " mensajes " y como tal, puede enviar un "mensaje" a cualquier objeto, incluso uno que no indique explícitamente en su interfaz que pueda aceptar. Como resultado, no existen elementos privados en Obj-C.

Esto puede ser muy poderoso, pero es una fuente de confusión para los nuevos programadores Obj-C, especialmente los que provienen de C ++, Java o C #. Aquí están las reglas básicas:

  • Debe definir todos los métodos públicos en su @interface para que los consumidores sepan qué mensajes espera manejar.
  • Debe definir los métodos @private en su @interface para evitar mensajes del compilador y evitar tener que ordenar los métodos en su @implementation.
  • Debe usar protocolos al implementar una convención particular de métodos para su clase.

Mucho de esto es preferencia personal, sin embargo, ayuda a evitar advertencias molestas del compilador y mantiene su código organizado. y fácil de entender.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top