¿Está Objective-C ‘más cerca del metal’ que Swift?

“Cerca del metal” puede significar algunas cosas diferentes.

Una interpretación de la frase es la compatibilidad con las características del lenguaje de nivel inferior . Como un superconjunto de C, Objective-C tiene muchas más características que Swift. Por ejemplo, puede escribir ensamblado desnudo en Objective-C de esta manera:

vacío en línea f () {
__asm ​​__ (“mov r0, r0”);
}

En Swift, no puedes escribir un ensamblaje en línea como ese. Objective-C también facilita la manipulación directa de RAM (debido a sus orígenes C también). Por ejemplo, puedo obtener un puntero a cualquier dirección de memoria arbitraria en Objective-C como esta:

nulo * p = (nulo *) 0x26ac89;

En Swift, me gritan por intentar hacer eso, y hay más guardias en el lugar cuando trabajo con tipos de puntero. Objective-C también pone a disposición funciones de memoria de nivel inferior como malloc , memcpy , etc., mientras que Swift abstrae más la administración de memoria. Esencialmente, es más fácil volverse loco con la memoria en Objective-C que en Swift. (Pero eso no significa que debas hacerlo).

Otra interpretación de “cerca del metal” podría ser el acceso a las capacidades de hardware . Aquí, Objective-C y Swift son idénticos, ya que ambos usan los mismos marcos Cocoa y Cocoa Touch. Ni Swift ni Objective-C le darán acceso a hardware que el otro no.

Finalmente, “cerca del metal” podría significar programar específicamente para una pieza de hardware, no un sistema operativo . Los sistemas integrados caen en esta categoría, por ejemplo. Aquí tampoco hay diferencia entre Objective-C y Swift, ya que ambos compilan en código de bytes LLVM y están construidos en el mismo tiempo de ejecución.

La primera definición (también conocida como características de lenguaje de nivel inferior) es lo que se me ocurrió primero, por lo que diría que Objective-C está “más cerca del metal” que Swift.

Esta es una pregunta un poco vieja, pero me topé con ella mientras navegaba por Quora y decidí actualizarla un poco …

Entonces, la respuesta de Tommy MacWilliam es bastante acertada en términos de cómo se ve el “metal desnudo”, pero podría usar algunas actualizaciones y correcciones.

Con Swift 2.0 y versiones posteriores (pronto se lanzará 3.0), la manipulación directa de la memoria es mucho más fácil. malloc, memcpy, etc. están disponibles, así como UnsafePointers genéricos que permiten la manipulación directa de la memoria e incluso el acceso arbitrario a la memoria (init con patrón de bits de dirección). UnsafePointers y todas sus variantes detalladas también le brindan un mejor control de la asignación / desasignación de memoria, por lo que realmente no se necesita malloc / free.

También están disponibles con prácticamente cualquier biblioteca de C, por lo que la interoperabilidad Objective-C no es necesaria, solo interoperabilidad C si desea hacer algunas cosas como el ensamblaje de bajo nivel (que aún no puede hacer en línea en Swift)

Finalmente, me gustaría aclarar una idea errónea, Swift no se ejecuta en el tiempo de ejecución de Objective-C. Puede, pero no exclusivamente. La interoperación de Objective-C Runtime fue esencial para que Apple obtuviera la adopción de Swift, pero Swift no lo requiere en absoluto.

El Objective-C es un tiempo de ejecución de despacho dinámico basado en mensajes, donde los nombres de clase, métodos, propiedades, etc. se llaman / recuperan dinámicamente por nombre de mensaje (de hecho, uno puede volcar fácilmente encabezados Obj-C completos desde un binario desde la clase / los nombres de métodos se almacenan en una estructura específica como cadenas simples).

Las clases rápidas, los métodos, las propiedades, etc. se envían estáticamente como las funciones de C, no hay intermediario de mensajería.

Entonces, en términos de cuál está “más cerca del metal”, Swift gana el pastel. Para todos los efectos, puede hacer casi cualquier cosa que pueda hacer en C en Swift, y también en C, aunque no será tan elegante como debería ser Swift.

Sin embargo, hay algunas cosas en las que Swift tiene un rendimiento inferior en lo que respecta al uso práctico en el mundo real. El rendimiento de la cadena deja mucho que desear, debido a la forma en que Swift maneja las cadenas (como vectores de puntos de código unicode de 32 bits), el rendimiento de la cadena no es lo que esperarías (aunque de nuevo puedes usar fácilmente UnsafeMutableBufferPointer para obtener C gusta el rendimiento), y dado que se centra en los tipos de valor, algunos algoritmos oscuros para manejar matrices también tienen un impacto en el rendimiento si escriben mucho para los pasos intermedios (Swift es copia en escritura, por lo que asigna un valor tipo instancia a un nuevo valor solo copia datos cuando se escribe en después). Por lo tanto, cosas como reducir, que crea valores intermedios y les escribe para cada paso, no son tan eficaces como uno quisiera. (Una vez más, eso se puede solucionar si te mueres por ganancias de rendimiento al hacerlo un poco más feo con UnsafePointers y al manipular la memoria sin procesar)

Dado que Objective-C es un superconjunto de C, se podría decir que está “más cerca del metal” que Swift. C se basa en punteros, acceso directo a memoria, bloques de memoria sin procesar, tipos enteros nativos, etc., de los cuales Swift intenta aislar a los desarrolladores hasta cierto punto (aunque Swift ofrece mecanismos para trabajar con estos cuando sea necesario). Pero desde el punto de vista de Las características orientadas a objetos en Objective-C que van más allá de C simple, los dos lenguajes son bastante similares en sus abstracciones de hardware.

Tenga en cuenta que la mayor parte de su aplicación será el código Cocoa o Cocoa Touch al que llame, y este código está altamente optimizado, escrito en Objective-C, casi no hará ninguna diferencia si usa Objective-C o Swift.

Además, ambos idiomas usan ARC, no recolección de basura, por lo que el rendimiento será predecible en ambos casos.