Ahora tenemos la notación "punto" para las propiedades. He visto varios vuelta y forths sobre los méritos de la notación de puntos frente a la notación mensaje. Para mantener las respuestas intactas, no voy a responder de ninguna manera en la pregunta.
¿Qué piensa acerca de la notación de puntos frente a la notación de mensajes para acceder a propiedades?
Intente mantenerlo enfocado en Objective-C; mi único sesgo que presentaré es que Objective-C es Objective-C, por lo que su preferencia de que sea como Java o JavaScript no es válida.
Los comentarios válidos tienen que ver con cuestiones técnicas (orden de las operaciones, precedencia del reparto, rendimiento, etc.), claridad (estructura frente a naturaleza del objeto, tanto a favor como en contra), concisión, etc.
Tenga en cuenta que soy de la escuela de calidad rigurosa y legibilidad en el código, habiendo trabajado en proyectos enormes donde la convención y la calidad del código son primordiales (el paradigma escribir una vez leído mil veces).
fuente
Respuestas:
No use el punto para el comportamiento. Utilice el punto para acceder o establecer atributos como cosas, normalmente atributos declarados como propiedades.
x = foo.name; // good foo.age = 42; // good y = x.retain; // bad k.release; // compiler should warn, but some don't. Oops. v.lockFocusIfCanDraw; /// ooh... no. bad bad bad
Para las personas nuevas en Objective-C, recomendaría no usar el punto para nada más que para cosas declaradas como @property. Una vez que tenga una idea del idioma, haga lo que le parezca correcto.
Por ejemplo, encuentro lo siguiente perfectamente natural:
k = anArray.count; for (NSView *v in myView.subviews) { ... };
Puede esperar que el analizador estático de clang aumente la capacidad de permitirle verificar que el punto se esté usando solo para ciertos patrones o no para ciertos otros patrones.
fuente
.uppercaseString
si la clase pudiera expresar su intención y tenerla ejecutado por el compilador. Quizás hay algo que me falta y que requiere la implementación actual de la notación de puntos.@property
solo, pero eso requeriría que el consumidor de una API aprenda otra dimensión booleana de información y que los diseñadores de API probablemente se ahoguen en argumentos sobre lo que debería y no debería ser un@property
. Tenga en cuenta que Xcode prefiere los@property
métodos implícitos al completar el código ... se recomienda, pero no se aplica.@property
declarados solo cuando sea nuevo en el idioma. A medida que uno gana confianza con la codificación en Objective-C, haga lo que le parezca correcto. Interesante; muchos de nosotros hemos vuelto al uso muy limitado del punto.Permítanme comenzar diciendo que comencé a programar en Visual / Real Basic, luego pasé a Java, así que estoy bastante acostumbrado a la sintaxis de puntos. Sin embargo, cuando finalmente me mudé a Objective-C y me acostumbré a los corchetes, luego vi la introducción de Objective-C 2.0 y su sintaxis de puntos, me di cuenta de que realmente no me gusta. (para otros idiomas está bien, porque así es como funcionan).
Tengo tres beefs principales con sintaxis de puntos en Objective-C:
Carne de res n. ° 1: No queda claro por qué podría estar recibiendo errores. Por ejemplo, si tengo la línea:
something.frame.origin.x = 42;
Entonces obtendré un error del compilador, porque
something
es un objeto, y no puede usar estructuras de un objeto como el lvalue de una expresión. Sin embargo, si tengo:something.frame.origin.x = 42;
Entonces esto se compila bien, porque
something
es una estructura en sí misma que tiene un miembro NSRect, y puedo usarlo como un lvalue.Si estuviera adoptando este código, necesitaría dedicar un tiempo a tratar de averiguar qué
something
es. ¿Es una estructura? ¿Es un objeto? Sin embargo, cuando usamos la sintaxis de corchetes, es mucho más claro:[something setFrame:newFrame];
En este caso, no hay absolutamente ninguna ambigüedad si
something
es un objeto o no. La introducción de la ambigüedad es mi problema número uno.Beef # 2: En C, la sintaxis de puntos se usa para acceder a miembros de estructuras, no a métodos de llamada. Los programadores pueden anular los métodos
setFoo:
yfoo
de un objeto, pero aún así acceder a ellos a través desomething.foo
. En mi mente, cuando veo expresiones que usan la sintaxis de puntos, espero que sean una simple asignación en un ivar. Este no es siempre el caso. Considere un objeto controlador que media una matriz y una vista de tabla. Si llamomyController.contentArray = newArray;
, esperaría que reemplazara la matriz anterior con la nueva matriz. Sin embargo, es posible que el programador original se haya anuladosetContentArray:
no solo para configurar la matriz, sino también para volver a cargar la vista de tabla. Desde la línea, no hay indicios de ese comportamiento. Si tuviera que ver[myController setContentArray:newArray];
, entonces pensaba "Ajá, un método. Necesito ir a ver la definición de este método sólo para asegurarme de saber lo que está haciendo".Así que creo que mi resumen de Beef # 2 es que puede anular el significado de la sintaxis de puntos con código personalizado.
Ternera # 3: Creo que se ve mal. Como programador de Objective-C, estoy totalmente acostumbrado a la sintaxis entre corchetes, por lo que leer y ver líneas y líneas de hermosos corchetes y luego romper repentinamente con,
foo.name = newName; foo.size = newSize;
etc., me distrae un poco. Me doy cuenta de que algunas cosas requieren sintaxis de puntos (estructuras C), pero esa es la única vez que las uso.Por supuesto, si está escribiendo código para usted mismo, use lo que le resulte cómodo. Pero si está escribiendo un código que está planeando en código abierto, o está escribiendo algo que no espera mantener para siempre, le recomiendo encarecidamente que use la sintaxis de corchetes. Esta es, por supuesto, solo mi opinión.
Publicación de blog reciente contra la sintaxis de puntos: http://weblog.bignerdranch.com/?p=83
Refutación a la publicación anterior: http://eschatologist.net/blog/?p=226 (con artículo original a favor de la sintaxis de puntos: http://eschatologist.net/blog/?p=160 )
fuente
something
lo general, es un objeto, pero me he encontrado con un par de lugares donde los autores originales han creado estructuras (para velocidad, menor uso de memoria, etc.), y tengo que pasar un buen par de minutos tratando de averiguar por qué el código no lo hace. t compilar.Soy un nuevo desarrollador de Cocoa / Objective-C, y mi opinión es la siguiente:
Me quedo con la notación de mensajería, aunque comencé con Obj-C 2.0, y aunque la notación de puntos me resulta más familiar (Java es mi primer idioma). Mi razón para esto es bastante simple: todavía no entiendo exactamente por qué agregaron la notación de puntos al idioma. A mí me parece una adición innecesaria, "impura". Aunque si alguien puede explicar cómo beneficia el idioma, me encantaría escucharlo.
Sin embargo, considero que esta es una elección estilística, y no creo que haya una forma correcta o incorrecta, siempre que sea coherente y legible , al igual que con cualquier otra opción estilística (como poner la llave de apertura en la misma línea que el encabezado del método o la siguiente línea).
fuente
La notación de puntos Objective-C es un azúcar sintáctico que se traduce al paso normal de mensajes, por lo que bajo el capó no cambia nada y no hace ninguna diferencia en tiempo de ejecución. La notación de puntos no es absolutamente más rápida que el paso de mensajes.
Después de este pequeño preámbulo necesario, he aquí los pros y los contras:
Pros y contras de la notación de puntos
pros
@property
notación de puntos y el compilador hace mucho trabajo por usted, puede generar código para una buena administración de memoria al obtener y configurar la propiedad; esta es la razón por la que las guías oficiales de Apple sugieren la notación de puntos.contras
@property
Ejemplos de código:
(1) Ejemplo de código de uso de operador compuesto:
//Use of compound operator on a property of an object anObject.var += 1; //This is not possible with standard message notation [anObject setVar:[anObject var] + 1];
fuente
Usar el estilo de un idioma, de acuerdo con el idioma en sí, es el mejor consejo aquí. Sin embargo, este no es un caso de escribir código funcional en un sistema OO (o viceversa) y la notación de puntos es parte de la sintaxis en Objective-C 2.0.
Se puede hacer un mal uso de cualquier sistema. La existencia del preprocesador en todos los lenguajes basados en C es suficiente para hacer cosas realmente bastante extrañas; solo mire el Concurso C ofuscado si necesita ver exactamente lo extraño que puede llegar a ser. ¿Significa eso que el preprocesador es automáticamente malo y que nunca debería usarlo?
El uso de la sintaxis de puntos para acceder a las propiedades, que se han definido como tales en la interfaz, está sujeto a abusos. La existencia de abuso in potentia no debería ser necesariamente un argumento en contra.
El acceso a la propiedad puede tener efectos secundarios. Esto es ortogonal a la sintaxis utilizada para adquirir esa propiedad. CoreData, delegación, propiedades dinámicas (primero + último = completo) necesariamente harán algún trabajo bajo las sábanas. Pero eso confundiría las 'variables de instancia' con las 'propiedades' de un objeto. No hay ninguna razón por la que las propiedades deban necesariamente almacenarse como están, especialmente si pueden calcularse (por ejemplo, la longitud de una cadena, por ejemplo). Entonces, ya sea que use foo.fullName o [foo fullName], todavía habrá una evaluación dinámica.
Por último, el comportamiento de la propiedad (cuando se usa como un valor l ) lo define el objeto mismo, como si se toma una copia o si se retiene. Esto hace que sea más fácil cambiar el comportamiento más adelante, en la propia definición de propiedad, en lugar de tener que volver a implementar los métodos. Eso se suma a la flexibilidad del enfoque, con la probabilidad resultante de que se produzcan menos errores (de implementación). Todavía existe la posibilidad de elegir el método incorrecto (es decir, copiar en lugar de retener) pero ese es un problema de arquitectura más que de implementación.
En última instancia, se reduce a la pregunta de '¿parece una estructura?'. Este es probablemente el principal diferenciador en los debates hasta ahora; si tiene una estructura, funciona de manera diferente que si tiene un objeto. Pero eso siempre ha sido cierto; no puede enviar una estructura a un mensaje, y necesita saber si está basado en pila o en referencia / malloc. Ya existen modelos mentales que difieren en términos de uso ([[CGRect alloc] init] o struct CGRect?). Nunca se han unificado en términos de comportamiento; necesita saber a qué se enfrenta en cada caso. Es muy poco probable que agregar denotaciones de propiedad para objetos confunda a cualquier programador que sepa cuáles son sus tipos de datos; y si no lo hacen, tienen problemas mayores.
En cuanto a consistencia; (Objetivo-) C es inconsistente en sí mismo. = se utiliza tanto para asignación como para igualdad, según la posición léxica en el código fuente. * se utiliza para punteros y multiplicaciones. Los BOOL son caracteres, no bytes (u otro valor entero), a pesar de que YES y NO son 1 y 0 respectivamente. La coherencia o la pureza no es para lo que se diseñó el lenguaje; se trataba de hacer las cosas.
Entonces, si no quiere usarlo, no lo use. Hágalo de una manera diferente. Si quiere usarlo y lo comprende, está bien si lo usa. Otros lenguajes tratan con los conceptos de estructuras de datos genéricas (mapas / estructuras) y tipos de objetos (con propiedades), a menudo usando la misma sintaxis para ambos a pesar de que uno es simplemente una estructura de datos y el otro es un objeto rico. Los programadores en Objective-C deben tener una capacidad equivalente para poder manejar todos los estilos de programación, incluso si no es el preferido.
fuente
Lo uso para propiedades porque
for ( Person *person in group.people){ ... }
es un poco más fácil de leer que
for ( Person *person in [group people]){ ... }
en el segundo caso, la legibilidad se interrumpe al poner su cerebro en modo de envío de mensajes, mientras que en el primer caso está claro que está accediendo a la propiedad de personas del objeto de grupo.
También lo usaré al modificar una colección, por ejemplo:
es un poco más legible que
El énfasis en este caso debería estar en la acción de agregar un objeto a la matriz en lugar de encadenar dos mensajes.
fuente
En su mayoría, me crié en la era de Objective-C 2.0 y prefiero la notación de puntos. Para mí, permite la simplificación del código, en lugar de tener corchetes adicionales, puedo usar un punto.
También me gusta la sintaxis de puntos porque me hace sentir que estoy accediendo a una propiedad del objeto, en lugar de simplemente enviarle un mensaje (por supuesto, la sintaxis de puntos realmente se traduce en el envío de mensajes, pero por el bien de las apariencias , el punto se siente diferente). En lugar de "llamar a un captador" con la sintaxis anterior, realmente se siente como si estuviera obteniendo algo útil directamente del objeto.
Parte del debate en torno a esto tiene que ver con "¡Pero ya tenemos sintaxis de puntos, y es para
structs
!". Y eso es cierto. Pero (y nuevamente, esto es solo psicológico) básicamente siento lo mismo para mí. Acceder a una propiedad de un objeto usando la sintaxis de puntos se siente igual que acceder a un miembro de una estructura, que es más o menos el efecto deseado (en mi opinión).**** Editar: como señaló bbum, también puede usar la sintaxis de puntos para llamar a cualquier método en un objeto (no lo sabía). Entonces diré que mi opinión sobre la sintaxis de puntos es solo para tratar con las propiedades de un objeto, no el envío de mensajes cotidianos **
fuente
Prefiero la sintaxis de mensajería ... pero solo porque eso es lo que aprendí. Teniendo en cuenta que muchas de mis clases y las que no están en el estilo Objective-C 1.0, no me gustaría mezclarlas. No tengo ninguna razón real además de "a lo que estoy acostumbrado" para no usar la sintaxis de puntos ... EXCEPTO por esto, esto me vuelve loco
No sé por qué, pero realmente me enfurece, sin una buena razón. Solo creo que haciendo
es más legible. ¡Pero a cada cual lo suyo!
fuente
[self.title lowercaseString]
o algo. Pero puedo ver estilísticamente por qué es molesto mezclar y combinar la sintaxis. La única razón por la que lo hago es para aclarar qué es una propiedad y qué es un método que devuelve un objeto (sé que las propiedades son realmente solo eso, pero espero que entiendas lo que quiero decir).Honestamente, creo que se trata de una cuestión de estilo. Personalmente, estoy en contra de la sintaxis de puntos (especialmente después de descubrir que puede usarla para llamadas a métodos y no solo para leer / escribir variables). Sin embargo, si lo va a usar, le recomiendo encarecidamente que no lo use para nada más que acceder y cambiar variables.
fuente
Una de las principales ventajas de la programación orientada a objetos es que no hay acceso directo al estado interno de los objetos.
La sintaxis de puntos me parece que es un intento de hacer que se vea y se sienta como si se estuviera accediendo directamente al estado. Pero en verdad, es solo azúcar sintáctico sobre los comportamientos -foo y -setFoo :. Yo prefiero llamar a las cosas por su nombre. La sintaxis de puntos ayuda a la legibilidad en la medida en que el código es más conciso, pero no ayuda a la comprensión porque no tener en cuenta que realmente está llamando -foo y -setFoo: podría significar problemas.
Los descriptores de acceso sintetizados me parecen un intento de facilitar la escritura de objetos en cuyo estado se accede directamente. Creo que esto fomenta exactamente el tipo de diseño de programa para el que se creó la programación orientada a objetos.
En general, preferiría que la sintaxis de puntos y las propiedades nunca se hayan introducido. Solía poder decirle a la gente que ObjC son algunas extensiones limpias de C para que se parezca más a Smalltalk, y ya no creo que eso sea cierto.
fuente
En mi opinión, la sintaxis de puntos hace que Objective-C sea menos Smalltalk-esque. Puede hacer que el código parezca más simple, pero agrega ambigüedad. ¿Es una
struct
,union
o un objeto?fuente
Mucha gente parece estar mezclando 'propiedades' con 'variables de instancia'. El objetivo de las propiedades es hacer posible modificar el objeto sin tener que conocer sus partes internas, creo. La variable de instancia es, la mayoría de las veces, la 'implementación' de una propiedad (que a su vez es la 'interfaz'), pero no siempre: a veces una propiedad no corresponde a un ivar, y en su lugar calcula un valor de retorno ' sobre la marcha'.
Por eso creo que la idea de que "la sintaxis de puntos te engaña haciéndote pensar que estás accediendo a la variable, por lo que es confuso" es incorrecta. Punto o corchete, no debe hacer suposiciones sobre los componentes internos: es una propiedad, no un ivar.
fuente
->
que cumple esa función (siempre que dichos ivars no tengan acceso restringido, por supuesto).Creo que podría cambiar a la mensajería en lugar de la notación de puntos porque en mi cabeza object.instanceVar es solo instanceVar que pertenece al objeto , para mí no se parece en nada a una llamada a un método , que es, así que podría haber cosas on en su descriptor de acceso y si usa instanceVar o self.instanceVar podría tener una diferencia mucho mayor que simplemente implícita versus explícita. Solo mis 2 ¢.
fuente
La notación de puntos intenta hacer que los mensajes parezcan accesos a un miembro de una estructura, lo que no es así. Podría funcionar bien en algunos casos. Pero pronto a alguien se le ocurrirá algo como esto:
NSView *myView = ...; myView.frame.size.width = newWidth;
Se ve bien. Pero no es. Es lo mismo que
que no funciona. El compilador acepta el primero, pero legítimamente no el segundo. E incluso si emitió un error o advertencia para el primero, esto es confuso.
fuente
Llámame vago pero si tuviera que escribir un sencillo '.' vs. dos [] cada vez para obtener los mismos resultados, preferiría una sola. Odio los lenguajes prolijos. El () en ceceo me volvió loco. El lenguaje elegante como las matemáticas es conciso y efectivo, todos los demás se quedan cortos.
fuente
Utilice la notación de puntos (siempre que pueda)
En los métodos de instancia que devuelven algún valor
No use notación de puntos
En los métodos de instancia que devuelven vacío, en los métodos init o en el método Class.
Y mi excepción favorita personal
NSMutableArray * array = @[].mutableCopy;
fuente
Personalmente, no uso la notación de puntos en el código. Solo lo uso en la expresión de enlace CoreData KVC cuando es necesario.
La razón para no usarlos en el código para mí es que la notación de puntos oculta la semántica del setter. Establecer una propiedad en notación de puntos siempre parece una asignación, independientemente de la semántica del establecedor (asignar / retener / copiar). El uso de la notación de mensaje hace visible que el objeto receptor tiene control sobre lo que sucede en el colocador y subraya el hecho de que esos efectos deben ser considerados.
Todavía estoy considerando si podría querer usar la notación de puntos al recuperar el valor de una propiedad declarada o compatible con KVC porque es cierto que es un poco más compacto y legible y no hay semántica oculta. En este momento me quedo con la notación de mensajes en aras de la coherencia.
fuente
De acuerdo, la notación de puntos en Objective-C parece extraña, de hecho. Pero todavía no puedo hacer lo siguiente sin él:
int width = self.frame.size.width;
Funciona bien, pero:
int height = [[[self frame] size] height];
Me da "No se puede convertir a un tipo de puntero". Sin embargo, realmente me gustaría que mi código se viera consistente con la notación de mensajes.
fuente
Esta es una gran pregunta y veo muchas respuestas diferentes. Aunque muchos han tocado los temas, intentaré responder esto desde un ángulo diferente (algunos podrían haberlo hecho implícitamente):
Si usamos la notación 'punto', la resolución del objetivo para el método se realiza en tiempo de compilación. Si usamos el paso de mensajes, la resolución del objetivo se pospone a la ejecución en tiempo de ejecución. Si los objetivos se resuelven en tiempo de compilación, la ejecución es más rápida, ya que resolver los objetivos en tiempo de ejecución incluye algunos gastos generales. (No es que la diferencia horaria importe mucho). Dado que ya hemos definido la propiedad en la interfaz del objeto, no tiene sentido diferenciar la resolución del objetivo para una propiedad en tiempo de ejecución y, por lo tanto, la notación de puntos es la notación que debemos usar para acceder a la propiedad.
fuente