objective c - sirven - ¿Cuál es la diferencia entre la sintaxis de puntos y la sintaxis de corchetes?
simbolos utilizados en los lenguajes de programacion (5)
Estoy repasando algunos recorridos para Objective-C y llegué a muchos lugares donde levanté las cejas. Me encantaría bajarlos.
¿Hay una diferencia fundamental en el envío de mensajes y las llamadas a métodos? Objective-C me permite hacer ambas cosas:
object.message
produce el mismo resultado que[object message]
. Creo que tal vez los mensajes anidados no se pueden crear usando la estrategia del operador punto.NSArray
un objetoNSArray
, ahora estoy a punto de imprimir resultados para esto usando unNSEnumerator
:id myObject = [object objectEnumerator];
en un ciclo de iteración e impresión de resultados. El tipo de
myObject
esid
, lo que significa que se resuelve en tiempo de ejecución y no en tiempo de compilación. Sé muy claramente qué tipo de objetos están almacenados en miNSArray
sonNSString
s, así que al cambiar el tipo deNSString * myObject
aNSString * myObject
, funciona muy bien. Sin embargo, experimenté y descubrí quemyObject
puede ser de cualquier tipo, ya seaNSString
oNSArray
oNSEnumerator
, y cualquiera de estos funciona perfectamente, iterando perfectamente el objetoNSArray
y produciendo los mismos resultados. ¿Que pasa con eso?
El envío de mensajes es la forma preferida de hacerlo. Es lo que usa la comunidad y refuerza el concepto de que los objetos se envían mensajes entre sí, lo que entra en juego más adelante cuando se trabaja con selectores y se pregunta a un objeto si responde a un selector (mensaje).
id
es básicamente un puntero a cualquier cosa. Se necesita algo de tiempo para acostumbrarse, pero es la base de cómo Objective-C maneja el tipado dinámico de objetos. CuandoNSLog()
encuentra con el especificador de formato%@
, envía un mensaje dedescription
al objeto que debería reemplazar al token (Esto se implementa en la superclaseNSObject
y puedeNSObject
en la subclase para obtener el resultado deseado).
En el futuro, cuando haga esto, le resultará más fácil hacer algo como esto:
for (NSString *s in YourNSArrayInstance) //assuming they are NSStrings as you described
{
NSLog(@"%@", s);
}
O simplemente simplemente:
for (NSString *s in YourNSArrayInstance) //assuming they are NSStrings as you described
NSLog(@"%@", s);
Aprenderá a agradar el envío de mensajes con el tiempo.
1) Ambos envían mensajes, solo una sintaxis diferente. [objeto de mensaje] es la sintaxis tradicional, object.message es la "notación de punto", pero significa exactamente lo mismo. Puede hacer algunos tipos de anidamiento con notación de puntos, pero no puede hacer nada con métodos que toman argumentos complejos. En general, los programadores antiguos de Obj-C no usan notación de puntos excepto para las llamadas de acceso simples. EN MI HUMILDE OPINIÓN.
2) El tiempo de ejecución es realmente inteligente y puede resolverlo sobre la marcha. El tipo de punteros es realmente una pista para que el compilador te avise cuando cometiste un error. No significa nada (en este caso) cuando el mensaje se envía a la matriz para recuperar un valor.
1: su terminología es incorrecta. El operador de punto no es "llamada de método", una operación diferente. Es solo una apariencia visual diferente para el envío de mensajes. No hay diferencia entre [xy] y xy. Sin embargo, la sintaxis de punto solo puede tener un argumento, ya que está destinado a ser utilizado solo para el acceso a la propiedad.
2: el tipo estático (tiempo de compilación) de un objeto no tiene ningún efecto sobre su comportamiento en el tiempo de ejecución. Su objeto sigue siendo un NSEnumerator incluso si lo está llamando de otra manera.
Es una distinción orientada a la persona que lee tu código. La sintaxis del punto indica el estado (estoy accediendo a un ivar), la sintaxis del método indica el comportamiento (estoy realizando alguna acción). Para el tiempo de ejecución, ambos son iguales.
Creo que la intención de Apple es mostrar los accesorios como un detalle de implementación del que no debe preocuparse. Incluso cuando pueden desencadenar efectos secundarios (debido a algún código adicional en el acceso), generalmente no lo hacen, por lo que la abstracción es imperfecta pero vale la pena (en mi humilde opinión). Otro inconveniente del uso de la notación de puntos es que realmente no se sabe si hay una estructura o una unión detrás de ella (que a diferencia del envío de mensajes, nunca dispara efectos secundarios cuando se le asigna). Tal vez Apple debería haber usado algo diferente de un punto. *shrugs*
Creo que tal vez los mensajes anidados no se pueden crear usando la estrategia del operador punto.
La notación de puntos se puede usar para anidar llamadas, pero tenga en cuenta lo siguiente:
shu.phyl.we.spaj.da
[[[[[shu]phyl]we]spaj]da]
En este caso, cuanto más feo, mejor. Ambos son un olor a código porque un objeto crea dependencias a otro objeto muy lejano, pero si usa corchetes para pasar mensajes, obtendrá esa sintaxis horrible adicional de la segunda línea, lo que hace que el código huela más fácilmente. Nuevamente, la convención es usar puntos para propiedades y corchetes para métodos.
No estoy seguro de qué tipo de distinción está tratando de hacer entre el "envío de mensajes" y el "método de llamada", ya que son dos formas de describir lo mismo. La sintaxis de puntos es solo un atajo para llamar a getters y setters, es decir:
[foo length]
foo.length
son exactamente lo mismo, como son:
[foo setLength:5]
foo.length = 5
Por lo general, solo debe usar la sintaxis de puntos cuando usa getters y setters; use la sintaxis del corchete cuadrado para todas sus otras llamadas a métodos.
Para su segunda pregunta: así es como funciona la tipificación dinámica. Cualquier tipo de declaraciones que ingrese en su código son sugerencias para el compilador; sus llamadas al método Objective-C siempre funcionarán siempre que los objetos respondan a ellas.