Recientemente compré una Mac y la uso principalmente para el desarrollo de C # en VMWare Fusion. Con todas las buenas aplicaciones para Mac, comencé a pensar en Xcode acechando con solo un clic de instalación y aprendiendo Objective-C.
La sintaxis entre los dos lenguajes se ve muy diferente, presumiblemente porque Objective-C tiene sus orígenes en C y C # tiene sus orígenes en Java / C ++. Pero se pueden aprender diferentes sintaxis, por lo que debería estar bien.
Mi principal preocupación es trabajar con el lenguaje y si ayudará a producir un código bien estructurado, legible y elegante. Realmente disfruto de características como LINQ y var en C # y me pregunto si hay equivalentes o características mejores / diferentes en Objective-C.
¿Qué características del lenguaje extrañaré desarrollar con Objective-C? ¿Qué características obtendré?
Editar: Las comparaciones de marcos son útiles e interesantes, pero una comparación de idiomas es lo que realmente está preguntando esta pregunta (en parte es mi culpa por etiquetar originalmente .net
). Presumiblemente, tanto Cocoa como .NET son marcos muy ricos por derecho propio y ambos tienen su propósito, uno dirigido a Mac OS X y el otro a Windows.
¡Gracias por los puntos de vista bien pensados y razonablemente equilibrados hasta ahora!
fuente
Respuestas:
Ningún lenguaje es perfecto para todas las tareas y Objective-C no es una excepción, pero hay algunas sutilezas muy específicas. Como usar
LINQ
yvar
(para el cual no tengo conocimiento de un reemplazo directo), algunos de estos están estrictamente relacionados con el lenguaje y otros están relacionados con el marco.( NOTA: así como C # está estrechamente acoplado con .NET, Objective-C está estrechamente acoplado con Cocoa. Por lo tanto, algunos de mis puntos pueden parecer no relacionados con Objective-C, pero Objective-C sin Cocoa es similar a C # sin .NET / WPF / LINQ, ejecutándose en Mono, etc. Simplemente no es la forma en que normalmente se hacen las cosas).
No pretendo explicar completamente las diferencias, los pros y los contras, pero aquí hay algunos que me vienen a la mente.
Una de las mejores partes de Objective-C es la naturaleza dinámica: en lugar de llamar a métodos, usted envía mensajes, que el tiempo de ejecución enruta dinámicamente. Combinado (juiciosamente) con la escritura dinámica, esto puede hacer que muchos patrones poderosos sean más simples o incluso triviales de implementar.
Como un superconjunto estricto de C, Objective-C confía en que usted sabe lo que está haciendo. A diferencia del enfoque administrado y / o seguro de tipos de lenguajes como C # y Java, Objective-C le permite hacer lo que quiera y experimentar las consecuencias. Obviamente, esto puede ser peligroso a veces, pero el hecho de que el lenguaje no te impida activamente hacer la mayoría de las cosas es bastante poderoso. ( EDITAR: Debo aclarar que C # también tiene características y funcionalidades "inseguras", pero su comportamiento predeterminado es el código administrado, que debe excluirse explícitamente. En comparación, Java solo permite el código de seguridad de tipos y nunca expone punteros sin formato en como lo hacen C y otros).
Las categorías (agregar / modificar métodos en una clase sin subclasificar o tener acceso a la fuente) es un arma de doble filo increíble. Puede simplificar enormemente las jerarquías de herencia y eliminar el código, pero si hace algo extraño, los resultados a veces pueden ser desconcertantes.
Cocoa hace que la creación de aplicaciones GUI sea mucho más simple de muchas maneras, pero tienes que entender el paradigma. El diseño MVC es omnipresente en Cocoa, y los patrones como delegados, notificaciones y aplicaciones GUI de subprocesos múltiples se adaptan bien a Objective-C.
Las uniones de Cocoa y la observación de valores clave pueden eliminar toneladas de código de pegamento, y los marcos de Cocoa aprovechan esto ampliamente. El envío dinámico de Objective-C trabaja de la mano con esto, por lo que el tipo de objeto no importa siempre que sea compatible con el valor clave.
Es probable que extrañe los genéricos y los espacios de nombres, y tienen sus beneficios, pero en la mentalidad y el paradigma de Objective-C, serían sutilezas en lugar de necesidades. (Los genéricos tienen que ver con la seguridad de tipos y evitar la conversión, pero la escritura dinámica en Objective-C hace que esto sea esencialmente un problema. Los espacios de nombres serían agradables si se hicieran bien, pero es lo suficientemente simple para evitar conflictos que el costo posiblemente supere los beneficios, especialmente para código heredado.)
Para la simultaneidad, Blocks (una nueva característica de lenguaje en Snow Leopard e implementada en decenas de API de Cocoa) son extremadamente útiles. Unas pocas líneas (con frecuencia combinadas con Grand Central Dispatch, que es parte de libsystem en 10.6) pueden eliminar un texto repetitivo significativo de funciones de devolución de llamada, contexto, etc. (Los bloques también se pueden usar en C y C ++, y ciertamente podrían agregarse a C #, lo cual sería increíble.) NSOperationQueue también es una forma muy conveniente de agregar simultaneidad a su propio código, enviando subclases personalizadas de NSOperation o bloques anónimos que GCD ejecuta automáticamente en uno o más subprocesos diferentes para usted.
fuente
alloca
. Simplemente no los hace tan accesibles; debe optar por participar explícitamente.He estado programando en C, C ++ y C # por más de 20 años, comencé en 1990. Acabo de decidir echar un vistazo al desarrollo de iPhone y Xcode y Objective-C. Oh Dios mío ... todas las quejas sobre Microsoft las retiro, ahora me doy cuenta de lo mal que ha estado el código. Objective-C es demasiado complejo en comparación con lo que hace C #. Me han echado a perder con C # y ahora aprecio todo el arduo trabajo que ha realizado Microsoft. Simplemente leer Objective-C con invocaciones de métodos es difícil de leer. C # es elegante en esto. Esa es solo mi opinión, esperaba que el lenguaje de desarrollo de Apple fuera tan bueno como los productos de Apple, pero querida, tienen mucho que aprender de Microsoft. No hay duda de que la aplicación C # .NET puedo poner una aplicación en funcionamiento muchas veces más rápido que XCode Objective-C. Apple ciertamente debería tomar una hoja del libro de Microsoft aquí y entonces tendríamos el entorno perfecto. :-)
fuente
"Just reading Objective-C with method invokes is difficult to read"
- Aquí hay solo un argumento muy subjetivo que se menciona aquí como contras de Obj-C. Todo lo demás es solo retórica discutible.No hay revisión técnica aquí, pero creo que Objective-C es mucho menos legible. Dado el ejemplo que le dio Cinder6:
C#
List<string> strings = new List<string>(); strings.Add("xyzzy"); // takes only strings strings.Add(15); // compiler error string x = strings[0]; // guaranteed to be a string strings.RemoveAt(0); // or non-existant (yielding an exception)
C objetivo
NSMutableArray *strings = [NSMutableArray array]; [strings addObject:@"xyzzy"]; [strings addObject:@15]; NSString *x = strings[0]; [strings removeObjectAtIndex:0];
Se ve horrible. Incluso intenté leer 2 libros sobre él, me perdieron al principio, y normalmente no lo entiendo con los libros / lenguajes de programación.
Me alegro de que tengamos Mono para Mac OS, porque si tuviera que confiar en Apple para que me diera un buen entorno de desarrollo ...
fuente
[NSMutableArray array]
(está perdiendo memoria) y la 4ª línea debería empezar conNSString* x
oid x
(error de compilación) ... Sí, Objective-C carece de genéricos (honestamente, no los extraño), no indexa objetos con sintaxis de matriz, y las API son generalmente más detalladas. To-may-to, to-mah-to. Realmente se reduce a lo que prefieres ver. (Podrías escribir el mismo código en C ++ STL y creo que es horrible). Para mí, el código legible a menudo significa que el texto del código te dice lo que está haciendo y, por lo tanto, es preferible el código Objective-C.List<T>.Remove
toma una cadena como argumento y elimina la primera aparición de esa cadena. Para eliminar por índice, necesitaRemoveAt
.removeObjectAtIndex:
, aunque más detallada, también es inequívoca en cuanto a lo que hace.strings[0]
ystrings.RemoveAt(0)
resta valor a la claridad, al menos para mí. (Además, siempre me molesta cuando los nombres de los métodos comienzan con una letra mayúscula ... Sé que es un pequeño inconveniente, pero es simplemente extraño)La administración de memoria manual es algo con lo que los principiantes en Objective-C parecen tener más problemas, principalmente porque piensan que es más complejo de lo que es.
Objective-C y Cocoa, por extensión, se basan en convenciones sobre la aplicación; conozca y siga un conjunto muy pequeño de reglas y obtendrá mucho gratis por el tiempo de ejecución dinámico a cambio.
La regla no es 100% verdadera, pero lo suficientemente buena para todos los días es:
alloc
debe coincidir con unrelease
al final del alcance actual.alloc
, debería ser devuelto por enreturn [value autorelease];
lugar de coincidir con unrelease
.Sigue la explicación más larga.
La gestión de la memoria se basa en la propiedad; solo el propietario de una instancia de objeto debería liberar el objeto, todos los demás no deberían hacer nada. Esto significa que en el 95% de todo el código se trata a Objective-C como si fuera una recolección de basura.
Entonces, ¿qué pasa con el otro 5%? Tiene tres métodos para buscar, cualquier instancia de objeto recibida de estos métodos es propiedad del alcance del método actual :
alloc
new
onewService
.copy
ymutableCopy
.El método tiene tres opciones posibles sobre qué hacer con sus instancias de objeto de propiedad antes de salir:
release
si ya no es necesario.autorelease
.Entonces, ¿cuándo debería tomar posesión proactivamente llamando
retain
? Dos casos:fuente
Claro, si todo lo que vio en su vida es el Objetivo C, entonces su sintaxis parece la única posible. Podríamos llamarte "programador virgen".
Pero dado que gran parte del código está escrito en C, C ++, Java, JavaScript, Pascal y otros lenguajes, verá que ObjectiveC es diferente de todos ellos, pero no en el buen sentido. ¿Tenían alguna razón para esto? Veamos otros lenguajes populares:
C ++ agregó muchos extras a C, pero cambió la sintaxis original solo en la medida necesaria.
C # agregó muchos extras en comparación con C ++, pero solo cambió las cosas que eran feas en C ++ (como eliminar el "::" de la interfaz).
Java cambió muchas cosas, pero mantuvo la sintaxis familiar, excepto en las partes donde se necesitaba el cambio.
JavaScript es un lenguaje completamente dinámico que puede hacer muchas cosas que ObjectiveC no puede. Aún así, sus creadores no inventaron una nueva forma de llamar a métodos y pasar parámetros solo para diferenciarse del resto del mundo.
Visual Basic puede pasar parámetros fuera de orden, al igual que ObjectiveC. Puede nombrar los parámetros, pero también puede pasarlos de la forma habitual. Independientemente de lo que use, es una forma normal delimitada por comas que todos entienden. La coma es el delimitador habitual, no solo en los lenguajes de programación, sino en libros, periódicos y lenguaje escrito en general.
Object Pascal tiene una sintaxis diferente a la de C, pero su sintaxis es en realidad MÁS FÁCIL de leer para el programador (tal vez no para la computadora, pero a quién le importa lo que piense la computadora). Entonces, tal vez se desviaron, pero al menos su resultado es mejor.
Python tiene una sintaxis diferente, que es incluso más fácil de leer (para humanos) que Pascal. Entonces, cuando lo cambiaron, haciéndolo diferente, al menos lo hicieron mejor para nosotros los programadores.
Y luego tenemos ObjectiveC. Añadiendo algunas mejoras a C, pero inventando su propia sintaxis de interfaz, llamadas a métodos, paso de parámetros y otras cosas. Me pregunto por qué no intercambiaron + y - de modo que más resta dos números. Hubiera sido aún más genial.
Steve Jobs se equivocó al apoyar a ObjectiveC. Por supuesto que no puede soportar C #, que es mejor, pero pertenece a su peor competidor. Así que esta es una decisión política, no práctica. La tecnología siempre sufre cuando las decisiones tecnológicas se toman por razones políticas. Debe liderar la empresa, lo que hace bien, y dejar los asuntos de programación a verdaderos expertos.
Estoy seguro de que habría incluso más aplicaciones para iPhone si decidiera escribir iOS y admitir bibliotecas en cualquier otro idioma que no sea ObjectiveC. Para todos, excepto para los fanáticos acérrimos, los programadores vírgenes y Steve Jobs, ObjectiveC parece ridículo, feo y repulsivo.
fuente
NSArray
y maneja la selección del mejor algoritmo basado en la máquina y la naturaleza de los datos.Una cosa que me encanta de aim-c es que el sistema de objetos se basa en mensajes, te permite hacer cosas realmente agradables que no podrías hacer en C # (¡al menos no hasta que admitan la palabra clave dinámica!).
Otra gran cosa acerca de escribir aplicaciones de cocoa es Interface Builder, es mucho mejor que el diseñador de formularios en Visual Studio.
Las cosas acerca de obj-c que me molestan (como desarrollador de C #) son el hecho de que tienes que administrar tu propia memoria (hay recolección de basura, pero eso no funciona en el iPhone) y que puede ser muy detallado debido a la sintaxis del selector y todos los [].
fuente
dynamic
solo lo llevará a la mitad: implementar un verdadero objeto dinámico, incluso con cosas triviales como la delegación de mensajes, es tedioso incluso en C # 4.0. Por otro lado, el precio por la flexibilidad del verdadero mensaje dinámico que pasa a la ObjC es el tipo perdido de seguridad.System.Reflection
combinado con extensiones en C # 3.0, puede llamar a cualquier método que encuentre, pero no es el verdadero paso de mensajes, se verá comoobj.PassMessage("function_name", params object[] args);
para un mejor paso de mensajes integrado en el lenguaje, el método que falta al que se puede llamar en un objeto normal sería necesario.Como programador que acaba de comenzar con Objective-C para iPhone, proveniente de C # 4.0, me faltan las expresiones lambda y, en particular, Linq-to-XML. Las expresiones lambda son específicas de C #, mientras que Linq-to-XML es en realidad más un contraste entre .NET y Cocoa. En una aplicación de muestra que estaba escribiendo, tenía algo de XML en una cadena. Quería analizar los elementos de ese XML en una colección de objetos.
Para lograr esto en Objective-C / Cocoa, tuve que usar la clase NSXmlParser . Esta clase se basa en otro objeto que implementa el protocolo NSXMLParserDelegate con métodos que se llaman (leer: mensajes enviados) cuando se lee una etiqueta abierta de elemento, cuando se leen algunos datos (generalmente dentro del elemento) y cuando se lee alguna etiqueta final de elemento . Debe realizar un seguimiento del estado y el estado del análisis. Y, sinceramente, no tengo idea de lo que sucede si el XML no es válido. Es genial para llegar a los detalles y optimizar el rendimiento, pero eso es mucho código.
Por el contrario, aquí está el código en C #:
using System.Linq.Xml; XDocument doc = XDocument.Load(xmlString); IEnumerable<MyCustomObject> objects = doc.Descendants().Select( d => new MyCustomObject{ Name = d.Value});
Y eso es todo, tienes una colección de objetos personalizados extraídos de XML. Si desea filtrar esos elementos por valor, o solo para aquellos que contienen un atributo específico, o si solo desea los primeros 5, o omitir el primer 1 y obtener los siguientes 3, o simplemente averiguar si se devolvió algún elemento ... BAM, todo está ahí en la misma línea de código.
Hay muchas clases de código abierto que facilitan mucho este procesamiento en Objective-C, por lo que hace gran parte del trabajo pesado. Simplemente no está tan integrado.
* NOTA: En realidad, no compilé el código anterior, solo es un ejemplo para ilustrar la relativa falta de verbosidad requerida por C #.
fuente
Probablemente la diferencia más importante es la gestión de la memoria. Con C # obtienes recolección de basura, en virtud de que es un lenguaje basado en CLR. Con Objective-C necesita administrar la memoria usted mismo.
Si viene de un entorno C # (o cualquier lenguaje moderno para el caso), pasar a un lenguaje sin administración automática de memoria será realmente doloroso, ya que dedicará gran parte de su tiempo de codificación a administrar correctamente la memoria (y depurar como bien).
fuente
Aquí hay un artículo bastante bueno que compara los dos idiomas: http://www.coderetard.com/2008/03/16/c-vs-objective-c/
fuente
Aparte de la diferencia de paradigma entre los 2 idiomas, no hay mucha diferencia. Por mucho que odie decirlo, puede hacer el mismo tipo de cosas (probablemente no tan fácilmente) con .NET y C # como con Objective-C y Cocoa. A partir de Leopard, Objective-C 2.0 tiene recolección de basura, por lo que no tiene que administrar la memoria usted mismo a menos que lo desee (la compatibilidad de código con Mac más antiguas y aplicaciones de iPhone son 2 razones para querer).
En lo que respecta al código estructurado y legible, gran parte de la carga recae en el programador, como con cualquier otro lenguaje. Sin embargo, encuentro que el paradigma de paso de mensajes se presta bien a un código legible siempre que nombre sus funciones / métodos de manera apropiada (nuevamente, como cualquier otro lenguaje).
Seré el primero en admitir que no estoy muy familiarizado con C # o .NET. Pero las razones por las que Quinn enumeró anteriormente son varias razones por las que no me importa serlo.
fuente
Las llamadas al método utilizadas en obj-c hacen que el código sea de fácil lectura, en mi opinión, mucho más elegante que c # y obj-c está construido sobre c, por lo que todo el código de c debería funcionar bien en obj-c. Sin embargo, lo más vendido para mí es que obj-c es un estándar abierto, por lo que puede encontrar compiladores para cualquier sistema.
fuente