¿Cuál es la diferencia entre la syntax de puntos y la syntax de corchetes?

Estoy repasando algunos recorridos para Objective-C y llegué a muchos lugares donde levanté las cejas. Me encantaría bajarlos.

  1. ¿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 nesteds no se pueden crear usando la estrategia del operador punto.

  2. NSArray un objeto NSArray , ahora estoy a punto de imprimir resultados para esto usando un NSEnumerator :

    id myObject = [object objectEnumerator];

    en un ciclo de iteración e impresión de resultados. El tipo de myObject es id , lo que significa que se resuelve en tiempo de ejecución y no en tiempo de comstackción. Sé muy claramente qué tipo de objetos están almacenados en mi NSArray son NSString s, así que al cambiar el tipo de NSString * myObject a NSString * myObject , funciona muy bien. Sin embargo, experimenté y descubrí que myObject puede ser de cualquier tipo, ya sea NSString o NSArray o NSEnumerator , y cualquiera de estos funciona perfectamente, iterando perfectamente el objeto NSArray y produciendo los mismos resultados. ¿Que pasa con eso?

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 syntax 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 syntax de puntos cuando usa getters y setters; use la syntax 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 comstackdor; sus llamadas al método Objective-C siempre funcionarán siempre que los objetos respondan a ellas.

Es una distinción orientada a la persona que lee tu código. La syntax del punto indica el estado (estoy accediendo a un ivar), la syntax 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 nesteds 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 syntax 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.

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 syntax 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 comstackció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.

1) Ambos envían mensajes, solo una syntax diferente. [objeto de mensaje] es la syntax 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 progtwigdores 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 comstackdor 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. El envío de mensajes es la forma preferida de hacerlo. Es lo que usa la comunidad y refuerza el concepto de objetos que 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).

  2. 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 dynamic de objetos. Cuando NSLog() encuentra con el especificador de formato %@ , envía un mensaje de description al objeto que debería reemplazar al token (Esto se implementa en la superclase NSObject y puede NSObject 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.