2010-05-17 7 views
49

En C o en cualquier lenguaje basado en ECMAscript usted 'llama a un método o función pública' en un objeto. Pero en la documentación para Objective C, no hay llamadas a métodos públicos, solo el envío de mensajes.'Llamar a un método' O 'enviar un mensaje' en el Objetivo C

¿Hay algo de malo en pensar que cuando 'envía un mensaje' en ObjC está 'llamando a un método público en un objeto'?

+0

+1 gran pregunta. Comprender la diferencia entre estos dos es (IMO) una clave para entender la flexibilidad de Objective-C. –

+4

piensa en esto, puede "enviar un mensaje a Nil" de manera segura, ¿puede "llamar a un método" de manera segura en un Nulo? –

Respuesta

53

Teóricamente, son diferentes.

Prácticamente, no tanto.

Son diferentes en Objective-C, los objetos pueden optar por no responder a los mensajes, o reenviar mensajes a diferentes objetos, o lo que sea. En idiomas como C, las llamadas a funciones realmente están saltando a cierto punto en la memoria y ejecutando el código. No hay un comportamiento dinámico involucrado.

Sin embargo, en casos de uso estándar, cuando envía un mensaje a un objeto, el método que el mensaje representa generalmente terminará siendo invocado. Entonces, aproximadamente el 99% de las veces, el envío de un mensaje dará lugar a una llamada a un método. Como tal, a menudo decimos "llamar a un método" cuando realmente queremos decir "enviar un mensaje". Prácticamente, casi siempre son lo mismo, pero no tienen que ser.

Hace un tiempo, me encerado filosófica sobre este tema y escribió sobre él: http://davedelong.tumblr.com/post/58428190187/an-observation-on-objective-c

edición

Para responder directamente a su pregunta, por lo general hay nada de malo en decir "llamar a un método" en lugar de "enviando un mensaje". Sin embargo, es importante entender que hay una diferencia de implementación muy significativa.

(Y como un aparte, mi preferencia personal es decir, "invocar un método en un objeto")

+1

puede actualizar el enlace a su blog? – pooya72

+0

También me gustaría ver la publicación del blog, si todavía se puede acceder de alguna forma. – obeattie

+1

@obeattie actualizado –

-5

Me enseñaron esto en mi clase de Java. Yo diría que solo tienen diferencias realistas en escenarios multiproceso, donde el paso de mensajes es una técnica muy legítima y de uso frecuente.

3

No, no hay nada malo con el pensamiento de esa manera. Se llaman mensajes porque son una capa de abstracción sobre las funciones. Parte de esto proviene del sistema de tipos de Objective C. Una mejor comprensión de los mensajes de ayuda:

full source on wikipedia (He recogido algunas de las cuestiones más relevantes)

nombres internos de la función son rara vez se utiliza directamente. Generalmente, los mensajes se convierten a las llamadas a función definidas en la biblioteca de tiempo de ejecución Objective-C . No es necesariamente conocido en el tiempo del enlace qué método se llamará a porque la clase del receptor (el objeto al que se envía el mensaje ) no necesita conocerse hasta el tiempo de ejecución .

de mismo artículo:

El modelo Objective-C de programación orientada a objetos se basa en el paso de mensajes a oponerse casos. En Objective-C uno no llama al ; uno envía un mensaje. El objeto al que se dirige el mensaje - el receptor - no garantiza la respuesta a un mensaje , y si no lo hace, simplemente hace una excepción. programación de estilo Smalltalk permite que los mensajes se implementen, con el método resuelto a su implementación en tiempo de ejecución. Para el ejemplo , se puede enviar un mensaje a una colección de objetos , a la que solo se espera que alguno responda, sin temor a producir errores de tiempo de ejecución . (La plataforma de cacao toma ventaja de esto, como todos los objetos en una aplicación cacao se envían al awakeFromNib:. Mensaje como se inicia la aplicación objetos pueden responden mediante la ejecución de cualquier inicialización requerida en el lanzamiento.) Pasando mensaje también hace no requiere que un objeto se defina en compilar tiempo.

18

Debido al envío de mensajes dinámicos de Objective-C, el envío de mensajes es realmente diferente de llamar a una función C o a un método C++ (aunque finalmente se llamará a una función C). Los mensajes se envían a través de selectores al objeto receptor, que responde al mensaje invocando un IMP (un puntero de función C) o reenviando el mensaje a su superclase. Si ninguna clase en la cadena de herencia responde al mensaje, se lanza una excepción. También es posible interceptar un mensaje y reenviarlo a una clase totalmente diferente (esto es lo que hacen las subclases NSProxy).

Cuando se utiliza Objective-C, no hay una gran diferencia entre el envío de mensajes y C++ - llamado método de estilo, pero hay algunas implicaciones prácticas del sistema de paso de mensajes, que yo sepa:

  1. Dado que el procesamiento del mensaje ocurre en tiempo de ejecución, en lugar de tiempo de compilación, no hay forma de tiempo de compilación para saber si una clase responde a un mensaje en particular. Esta es la razón por la cual generalmente obtienes advertencias de compilador en lugar de errores cuando escribes mal un método, por ejemplo.
  2. Puede enviar cualquier mensaje de forma segura a nil, lo que permite modismos como [foo release] sin preocuparse por comprobar NULL.
  3. Como dice @CrazyJugglerDrummer, el envío de mensajes le permite enviar mensajes a una gran cantidad de objetos a la vez sin preocuparse de si responderán a ellos. Esto permite protocolos informales y enviar mensajes a todos los objetos en un contenedor.
  4. No estoy 100% seguro de esto, pero creo que las categorías (agregando métodos a clases ya existentes) son posibles a través del envío de mensajes dinámicos.
  5. El envío de mensajes permite el reenvío de mensajes (por ejemplo, con las subclases NSProxy).
  6. El envío de mensajes le permite realizar hackeos de bajo nivel interesantes, como el método swizzling (intercambio de implementaciones de métodos en tiempo de ejecución).
+3

Es cierto que soy un principiante de Objective-C, pero ¿no te refieres a '[foo release]'? – sblom

1

En una llamada de función C, el compilador reemplaza el selector con una llamada a una función y la ejecución salta en respuesta a la llamada a la función.

En Objective-C, los métodos se vinculan dinámicamente a los mensajes, lo que significa que los nombres de los métodos se resuelven en implementaciones en tiempo de ejecución. Específicamente, el objeto se examina en tiempo de ejecución para ver si contiene un puntero a una implementación para el selector dado.

Como consecuencia, Objective-C le permite cargar y vincular nuevas clases y categorías mientras se está ejecutando, y realizar técnicas como swizzling, categorías, proxies de objetos y otros. Nada de esto es posible en C.

Cuestiones relacionadas