Objective-C es un lenguaje de programación orientado a objetos de alto nivel y propósito general que agrega paso de mensajes (mensajería) al estilo Smalltalk al lenguaje de programación C. [ 3 ] Desarrollado originalmente por Brad Cox y Tom Love a principios de la década de 1980, fue seleccionado por NeXT para su sistema operativo NeXTSTEP . Debido al linaje directo de Apple macOS con NeXTSTEP, [ 4 ] Objective-C fue el lenguaje estándar utilizado, soportado y promovido por Apple para desarrollar aplicaciones macOS e iOS (a través de sus respectivas interfaces de programación de aplicaciones ( API ), Cocoa y Cocoa Touch ) desde 1997, cuando Apple compró NeXT, hasta la introducción del lenguaje Swift en 2014. [ 5 ]
Los programas Objective-C desarrollados para sistemas operativos que no sean de Apple o que no dependan de las API de Apple también pueden compilarse para cualquier plataforma compatible con GNU , GNU Compiler Collection (GCC) o LLVM / Clang .
Los archivos de código fuente de Objective-C que se utilizan para "mensajería/implementación" suelen tener .mextensiones de archivo, mientras que los archivos de encabezado/interfaz de Objective-C tienen .hextensiones, al igual que los archivos de encabezado de C. Los archivos de Objective-C++ se identifican con una .mmextensión de archivo.
Historia
Objective-C fue creado principalmente por Brad Cox y Tom Love a principios de la década de 1980 en su empresa Productivity Products International (PPI) . [ 6 ] [ 7 ]
Antes de la creación de su empresa, ambos habían conocido Smalltalk en el Centro de Tecnología de Programación de ITT Corporation en 1981. Los primeros trabajos sobre Objective-C se remontan a esa época. [ 8 ] A Cox le intrigaban los problemas de la verdadera reutilización en el diseño y la programación de software. Comprendió que un lenguaje como Smalltalk sería invaluable para crear entornos de desarrollo para los desarrolladores de sistemas en ITT. Sin embargo, él y Tom Love también reconocieron que la compatibilidad con versiones anteriores de C era de vital importancia en el entorno de ingeniería de telecomunicaciones de ITT. [ 9 ]
Cox comenzó a escribir un preprocesador para C para agregar algunas de las capacidades de Smalltalk . Pronto tuvo una implementación funcional de una extensión orientada a objetos para el lenguaje C , que llamó Precompilador Orientado a Objetos (OOPC). [ 10 ] Love fue contratado por Schlumberger Research en 1982 y tuvo la oportunidad de adquirir la primera copia comercial de Smalltalk-80, lo que influyó aún más en el desarrollo de su creación. [ 11 ] Para demostrar que se podía hacer un progreso real, Cox mostró que hacer componentes de software intercambiables realmente solo requería algunos cambios prácticos en las herramientas existentes. Específicamente, debían admitir objetos de manera flexible, venir provistos de un conjunto de bibliotecas utilizables y permitir que el código (y cualquier recurso que el código necesitara) se empaquetara en un formato multiplataforma .
Love y Cox finalmente fundaron PPI para comercializar su producto. Para evitar disputas legales con sus empleadores anteriores, Cox reimplementó su compilador para el lenguaje, que pasó a llamarse "Objective-C". La línea principal de productos de la compañía consistía en este compilador, junto con bibliotecas de clases diseñadas para usarse con él. [ 11 ] En 1986, Cox publicó la descripción principal de Objective-C en su forma original en el libro Object-Oriented Programming: An Evolutionary Approach . Aunque se cuidó de explicar que el problema de la reutilización va más allá de lo que proporciona Objective-C, el lenguaje a menudo se comparaba característica por característica con otros lenguajes.
Popularización a través de NeXT
En 1988, NeXT obtuvo la licencia de Objective-C de StepStone (el nuevo nombre de PPI, propietario de la marca registrada Objective-C) y amplió el compilador GCC para que fuera compatible con Objective-C. NeXT desarrolló las bibliotecas Application Kit (AppKit) y Foundation Kit, sobre las que se basaron la interfaz de usuario de NeXTSTEP y Interface Builder. Si bien las estaciones de trabajo de NeXT no tuvieron un gran impacto en el mercado, sus herramientas fueron ampliamente elogiadas en la industria. NeXT abandonó la producción de hardware y se centró en el desarrollo de software, comercializando NeXTSTEP (y OPENSTEP) como plataforma para programación personalizada.
Para eludir los términos de la GPL , NeXT tenía previsto inicialmente distribuir el frontend de Objective-C por separado, permitiendo al usuario enlazarlo con GCC para generar el ejecutable del compilador. Aunque inicialmente fue aceptado por Richard M. Stallman , este plan fue rechazado después de que Stallman consultara con los abogados de GNU y NeXT accediera a integrar Objective-C en GCC. [ 12 ]
El trabajo para extender GNU Compiler Collection (GCC) fue liderado por Steve Naroff, quien se unió a NeXT procedente de StepStone. Los cambios del compilador se publicaron bajo los términos de la Licencia Pública General de GNU (GPL), pero las bibliotecas de tiempo de ejecución no, lo que hizo que la contribución de código abierto no fuera utilizable por el público en general. Esto llevó a que otras partes desarrollaran dichas bibliotecas de tiempo de ejecución bajo licencias de código abierto. Posteriormente, Steve Naroff también fue uno de los principales colaboradores en el trabajo de Apple para construir el frontend de Objective-C para Clang . [ 13 ]
El proyecto GNU comenzó a trabajar en su implementación de software libre de Cocoa , llamada GNUstep , basada en el estándar OpenStep . [ 14 ] Dennis Glatting escribió el primer entorno de ejecución de GNU Objective-C en 1992. El entorno de ejecución de GNU Objective-C actual, en uso desde 1993, es el desarrollado por Kresten Krab Thorup mientras era estudiante universitario en Dinamarca . [ 15 ] Thorup también trabajó en NeXT de 1993 a 1996. [ 16 ]
Desarrollo de Apple y Swift
Tras adquirir NeXT en 1996, Apple Computer utilizó OpenStep en su entonces nuevo sistema operativo, Mac OS X. Esto incluía Objective-C, la herramienta de desarrollo basada en Objective-C de NeXT, Project Builder , y su herramienta de diseño de interfaces, Interface Builder . Ambas se fusionaron posteriormente en una sola aplicación, Xcode . La mayor parte de la API Cocoa actual de Apple se basa en objetos de interfaz de OpenStep y es el entorno Objective-C más importante que se utiliza para el desarrollo activo.
En la Conferencia Mundial de Desarrolladores (WWDC) de 2014, Apple presentó un nuevo lenguaje, Swift , que se caracterizó como "Objective-C sin la C". [ 17 ]
Sintaxis
Objective-C es una capa delgada sobre C y es un " superconjunto estricto " de C, lo que significa que es posible compilar cualquier programa C con un compilador Objective-C e incluir libremente código del lenguaje C dentro de una clase Objective-C. [ 18 ] [ 19 ] [ 20 ] [ 21 ]
Objective-C deriva su sintaxis de objetos de Smalltalk . Toda la sintaxis para operaciones no orientadas a objetos (incluidas variables primitivas, preprocesamiento, expresiones, declaraciones de funciones y llamadas a funciones) es idéntica a la de C, mientras que la sintaxis para características orientadas a objetos es una implementación de la mensajería al estilo Smalltalk.
Mensajes
El modelo Objective-C de programación orientada a objetos se basa en el paso de mensajes a instancias de objetos. En Objective-C, no se llama a un método ; se envía un mensaje . Esto difiere del modelo de programación estilo Simula utilizado por C++ . La diferencia entre estos dos conceptos radica en cómo se ejecuta el código referenciado por el nombre del método o mensaje. En un lenguaje estilo Simula, el nombre del método, en la mayoría de los casos, se vincula a una sección de código en la clase de destino mediante el compilador. En Smalltalk y Objective-C, el destino de un mensaje se resuelve en tiempo de ejecución, y el objeto receptor interpreta el mensaje. Un método se identifica mediante un selector o SELun identificador único para cada nombre de mensaje, a menudo una cadena terminada en que representa su nombre, y se resuelve en un puntero a un método C que lo implementa : un . [ 22 ] Una consecuencia de esto es que el sistema de paso de mensajes no tiene comprobación de tipos. No se garantiza que el objeto al que se dirige el mensaje —el receptor— responda a un mensaje, y si no lo hace, genera una excepción. [ 23 ]NULIMP
Para enviar el mensaje methodal objeto al que apunta el puntero, objse necesitaría el siguiente código en C++ :
obj -> método ( argumento );En Objective-C, esto se escribe de la siguiente manera:
[ método obj : argumento ];La llamada al "método" es traducida por el compilador a la objc_msgSend(id self, SEL op, ...)familia de funciones de tiempo de ejecución. [ 24 ] Diferentes implementaciones manejan adiciones modernas como super. [ 25 ] En las familias GNU, esta función se llama objc_msg_sendv, pero ha sido descontinuada en favor de un sistema de búsqueda moderno en objc_msg_lookup. [ 26 ]
Ambos estilos de programación presentan múltiples ventajas y desventajas. La programación orientada a objetos en el estilo Simula ( C++ ) permite la herencia múltiple y una ejecución más rápida mediante el enlace en tiempo de compilación siempre que sea posible, pero no admite el enlace dinámico por defecto. Además, obliga a que todos los métodos tengan una implementación correspondiente, a menos que sean abstractos . La programación al estilo Smalltalk, utilizada en Objective-C, permite que los mensajes no estén implementados, y que el método se resuelva a su implementación en tiempo de ejecución. Por ejemplo, se puede enviar un mensaje a una colección de objetos, de los cuales solo algunos responderán, sin temor a producir errores en tiempo de ejecución. El paso de mensajes tampoco requiere que un objeto esté definido en tiempo de compilación . Sin embargo, se requiere una implementación para que el método se llame en el objeto derivado. (Consulte la sección de tipado dinámico a continuación para obtener más información sobre las ventajas del enlace dinámico (tardío)).
Interfaces e implementaciones
Objective-C requiere que la interfaz y la implementación de una clase se declaren en bloques de código separados. Por convención, los desarrolladores colocan la interfaz en un archivo de cabecera y la implementación en un archivo de código. Los archivos de cabecera, normalmente con la extensión .h, son similares a los archivos de cabecera de C, mientras que los archivos de implementación (métodos), normalmente con la extensión .m, pueden ser muy similares a los archivos de código de C.
Interfaz
Esto es análogo a las declaraciones de clase que se utilizan en otros lenguajes orientados a objetos, como C++ o Python.
La interfaz de una clase generalmente se define en un archivo de cabecera. Una convención común es nombrar el archivo de cabecera con el nombre de la clase, por ejemplo, Ball.hcontendría la interfaz para la clase Ball.
Una declaración de interfaz tiene la siguiente forma:
@interface ClassName : SuperclassName { // variables de instancia } + classMethod1 ; + ( return_type ) classMethod2 ; + ( return_type ) classMethod3: ( param1_type ) param1_varName ;- ( tipo_retorno ) método_instancia1con1parámetro: ( tipo_param1 ) nombre_var_param1 ; - ( tipo_retorno ) método2con2parámetros de instancia: ( tipo_param1 ) nombre_var_param1 nombre_llamada_param : (tipo_param2 ) nombre_var_param2 ; @finEn lo anterior, los signos más indican métodos de clase , es decir, métodos que se pueden llamar en la clase misma (no en una instancia), y los signos menos indican métodos de instancia , que solo se pueden llamar en una instancia particular de la clase. Los métodos de clase tampoco tienen acceso a las variables de instancia .
El código anterior es aproximadamente equivalente a la siguiente interfaz de C++ :
clase ClassName : public SuperclassName { protected : // variables de instanciapúblico : // Funciones de clase (estáticas) static void * classMethod1 (); static return_type classMethod2 (); static return_type classMethod3 ( param1_type param1_varName );// Funciones de instancia (miembro) return_type instanceMethod1With1Parameter ( param1_type param1_varName ); return_type instanceMethod2With2Parameters ( param1_type param1_varName , param2_type param2_varName = default ); };Nótese que esto instanceMethod2With2Parameters:param2_callName:demuestra la intercalación de segmentos de selector con expresiones de argumentos, para lo cual no existe un equivalente directo en C/C++.
Los tipos de retorno pueden ser cualquier tipo estándar de C , un puntero a un objeto genérico de Objective-C, un puntero a un tipo específico de objeto como NSArray *, NSImage * o NSString *, o un puntero a la clase a la que pertenece el método (tipo de instancia). El tipo de retorno predeterminado es el tipo genérico de Objective-C id.
Los argumentos de un método comienzan con un nombre que identifica el argumento que forma parte del nombre del método, seguido de dos puntos, el tipo de argumento esperado entre paréntesis y el nombre del argumento. El nombre del argumento puede omitirse.
- ( void ) setRangeStart: ( int ) start end: ( int ) end ; - ( void ) importDocumentWithName: ( NSString * ) name withSpecifiedPreferences :( Preferences * ) prefs beforePage :( int ) insertPage ;Una derivación de la definición de interfaz es la categoría , que permite agregar métodos a clases existentes. [ 27 ]
Implementación
La interfaz solo declara la interfaz de la clase y no los métodos en sí: el código real se escribe en el archivo de implementación. Los archivos de implementación (métodos) normalmente tienen la extensión de archivo .m, que originalmente significaba "mensajes". [ 28 ]
@implementation classname + ( return_type ) classMethod { // implementación } - ( return_type ) instanceMethod { // implementación } @endLos métodos se escriben utilizando sus declaraciones de interfaz. Comparando Objective-C y C:
- ( int ) método: ( int ) i { return [ self raíz_cuadrada : i ]; }función entera ( int i ) { devuelve raíz cuadrada ( i ); }La sintaxis permite la pseudonominación de argumentos .
- ( void ) changeColorToRed: ( float ) red green: ( float ) green blue: ( float ) blue { //... Implementación ... }// Llamado de esta manera: [ myColor changeColorToRed : 5.0 green : 2.0 blue : 6.0 ];Las representaciones internas de un método varían entre las distintas implementaciones de Objective-C. Si `myColor` pertenece a la clase Color, el método de instancia -changeColorToRed:green:blue:podría estar etiquetado internamente como ` _i_Color_changeColorToRed_green_blue.`. El `.` ise utiliza para referirse a un método de instancia, con la clase y luego los nombres de los métodos añadidos y los dos puntos reemplazados por guiones bajos. Dado que el orden de los parámetros forma parte del nombre del método, no se puede modificar para adaptarlo al estilo de codificación o a la expresión, como ocurre con los parámetros con nombre.
Sin embargo, los nombres internos de las funciones rara vez se utilizan directamente. Generalmente, los mensajes se convierten en llamadas a funciones definidas en la biblioteca de tiempo de ejecución de Objective-C. No es necesario saber en tiempo de enlace qué método se llamará, ya que la clase del receptor (el objeto al que se envía el mensaje) no necesita conocerse hasta el tiempo de ejecución.
Instanciación
Una vez escrita una clase en Objective-C, se puede instanciar. Esto se logra asignando primero una instancia no inicializada de la clase (un objeto) y luego inicializándola. Un objeto no es completamente funcional hasta que se hayan completado ambos pasos. Estos pasos deben realizarse con una sola línea de código para que nunca exista un objeto asignado que no haya sido inicializado (y porque no es recomendable conservar el resultado intermedio, ya que -initpuede devolver un objeto diferente al que se llama).
Instanciación con el inicializador predeterminado sin parámetros:
MyObject * foo = [[ MyObject alloc ] init ];Instanciación con un inicializador personalizado:
MyObject * foo = [[ MyObject alloc ] initWithString : myString ];En el caso de que no se realice ninguna inicialización personalizada, a menudo se puede utilizar el método "new" en lugar de los mensajes alloc-init:
MyObject * foo = [ MyObject new ];Además, algunas clases implementan inicializadores de métodos de clase. Al igual que +new, combinan +allocy -init, pero a diferencia de +new, devuelven una instancia con liberación automática. Algunos inicializadores de métodos de clase aceptan parámetros:
MyObject * foo = [ MyObject object ]; MyObject * bar = [ MyObject objectWithString : @"Wikipedia :)" ];El mensaje `alloc` asigna suficiente memoria para almacenar todas las variables de instancia de un objeto, establece todas las variables de instancia a valores cero y convierte la memoria en una instancia de la clase; en ningún momento durante la inicialización la memoria es una instancia de la superclase.
El mensaje init realiza la configuración de la instancia al crearse. El método init suele escribirse de la siguiente manera:
- ( id ) init {self = [ super init ];si ( self ) {// Inicializa el objeto aquí}regresar a sí mismo ;}En el ejemplo anterior, observe el idtipo de retorno. Este tipo representa un puntero a cualquier objeto en Objective-C (consulte la sección de tipado dinámico ).
El patrón inicializador se utiliza para asegurar que el objeto sea inicializado correctamente por su superclase antes de que el método init realice su inicialización. Realiza las siguientes acciones:
- Línea 2
- Envía un
initmensaje a la instancia de la superclase y asigna el resultado aself(puntero al objeto actual).
- Envía un
- Línea 3
- Comprueba si el puntero al objeto devuelto es válido antes de realizar cualquier inicialización.
- Línea 6
- Devuelve el valor de sí mismo a quien realiza la llamada.
Un puntero a objeto no válido tiene el valor nil; las sentencias condicionales iftratan a nil como un puntero nulo, por lo que el código de inicialización no se ejecutará si [super init]devuelve nil. Si hay un error en la inicialización, el método init debe realizar cualquier limpieza necesaria, incluido el envío de un releasemensaje a sí mismo, y devolver nilpara indicar que la inicialización falló. Cualquier comprobación de tales errores solo debe realizarse después de haber llamado a la inicialización de la superclase para garantizar que la destrucción del objeto se realizará correctamente.
Si una clase tiene más de un método de inicialización, solo uno de ellos (el inicializador designado ) necesita seguir este patrón; los demás deben llamar al inicializador designado en lugar del inicializador de la superclase.
Protocolos
En otros lenguajes de programación, se les llama interfaces .
Objective-C se amplió en NeXT para introducir el concepto de herencia múltiple de especificaciones, pero no de implementación, mediante la introducción de protocolos . Este patrón se puede lograr como una clase base abstracta de herencia múltiple en C++ o como una interfaz (como en Java y C# ). Objective-C utiliza protocolos ad hoc, denominados protocolos informales , y protocolos impuestos por el compilador, denominados protocolos formales .
Un protocolo informal es una lista de métodos que una clase puede optar por implementar. Se especifica en la documentación, ya que no está presente en el lenguaje. Los protocolos informales se implementan como una categoría (véase más abajo) en NSObject y suelen incluir métodos opcionales que, si se implementan, pueden cambiar el comportamiento de una clase. Por ejemplo, una clase de campo de texto podría tener un delegado que implemente un protocolo informal con un método opcional para realizar el autocompletado del texto escrito por el usuario. El campo de texto descubre si el delegado implementa ese método (mediante programación reflexiva ) y, en caso afirmativo, llama al método del delegado para habilitar la función de autocompletado.
Un protocolo formal es similar a una interfaz en Java, C# y Ada 2005. Se trata de una lista de métodos que cualquier clase puede declarar que implementará. Las versiones de Objective-C anteriores a la 2.0 requerían que una clase implementara todos los métodos de un protocolo que declarara adoptar; el compilador generaría un error si la clase no implementaba todos los métodos de sus protocolos declarados. Objective-C 2.0 añadió soporte para marcar ciertos métodos de un protocolo como opcionales, y el compilador no exigirá la implementación de métodos opcionales.
Para que una clase se considere conforme a un protocolo, debe declararse que lo implementa. Esto se puede detectar en tiempo de ejecución. Los protocolos formales no proporcionan implementaciones; simplemente garantizan a quienes los utilizan que las clases que se ajustan al protocolo sí las proporcionarán. En la biblioteca NeXT/Apple, el sistema de objetos distribuidos utiliza con frecuencia protocolos para representar las capacidades de un objeto que se ejecuta en un sistema remoto.
La sintaxis
@protocol NSLocking - ( void ) lock ; - ( void ) unlock ; @enddenota que existe la idea abstracta de bloqueo. Al indicar en la definición de la clase que el protocolo está implementado,
@interface NSLock : NSObject < NSLocking > // ... @endLas instancias de NSLock afirman que proporcionarán una implementación para los dos métodos de instancia.
Tipografía dinámica
Objective-C, al igual que Smalltalk, puede usar tipado dinámico : se puede enviar un mensaje a un objeto que no esté especificado en su interfaz. Esto permite una mayor flexibilidad, ya que permite que un objeto "capture" un mensaje y lo envíe a otro objeto que pueda responder adecuadamente, o bien, que lo envíe a otro objeto. Este comportamiento se conoce como reenvío de mensajes o delegación (véase más abajo). Alternativamente, se puede usar un manejador de errores en caso de que el mensaje no se pueda reenviar. Si un objeto no reenvía un mensaje, no responde a él o no maneja un error, el sistema generará una excepción en tiempo de ejecución. [ 29 ] Si los mensajes se envían a nil (el puntero de objeto nulo), se ignorarán silenciosamente o generarán una excepción genérica, según las opciones del compilador.
También se puede añadir información de tipado estático a las variables de forma opcional. Esta información se verifica en tiempo de compilación. En las siguientes cuatro instrucciones, se proporciona información de tipo cada vez más específica. Las instrucciones son equivalentes en tiempo de ejecución, pero la información adicional permite al compilador advertir al programador si el argumento pasado no coincide con el tipo especificado.
- ( void ) setMyValue: ( id ) foo ;En la declaración anterior, foo puede ser de cualquier clase.
- ( void ) setMyValue: ( id < NSCopying > ) foo ;En la declaración anterior, foo puede ser una instancia de cualquier clase que cumpla con el NSCopyingprotocolo.
- ( void ) setMyValue: ( NSNumber * ) foo ;En la declaración anterior, foo debe ser una instancia de la clase NSNumber .
- ( void ) setMyValue: ( NSNumber < NSCopying > * ) foo ;En la declaración anterior, foo debe ser una instancia de la clase NSNumber y debe ajustarse al NSCopyingprotocolo.
En Objective-C, todos los objetos se representan como punteros y no se permite la inicialización estática. El objeto más simple es el tipo al que apunta `id ( objc_obj * )`, que solo tiene un puntero `isa` que describe su clase. Otros tipos de C, como los valores y las estructuras, permanecen sin cambios porque no forman parte del sistema de objetos. Esta decisión difiere del modelo de objetos de C++, donde las estructuras y las clases están unificadas.
Reenvío
Objective-C permite enviar un mensaje a un objeto que puede no responder. En lugar de responder o simplemente descartar el mensaje, un objeto puede reenviarlo a otro que sí pueda responder. El reenvío puede utilizarse para simplificar la implementación de ciertos patrones de diseño , como el patrón observador o el patrón proxy .
El entorno de ejecución de Objective-C especifica un par de métodos enObject
- métodos de reenvío:
- ( retval_t ) forward: ( SEL ) sel args: ( arglist_t ) args ; // con GCC - ( id ) forward: ( SEL ) sel args: ( marg_list ) args ; // con sistemas NeXT/Apple
- métodos de acción:
- ( retval_t ) performv: ( SEL ) sel args: ( arglist_t ) args ; // con GCC - ( id ) performv: ( SEL ) sel args: ( marg_list ) args ; // con sistemas NeXT/Apple
Un objeto que desee implementar el reenvío solo necesita sobrescribir el método de reenvío con un nuevo método para definir el comportamiento de reenvío. performv::No es necesario sobrescribir el método de acción, ya que este simplemente realiza una acción en función del selector y los argumentos. Observe el SELtipo, que es el tipo de mensajes en Objective-C.
Nota: en OpenStep, Cocoa y GNUstep, los frameworks más utilizados de Objective-C, no se utiliza la Objectclase. El método de la clase se utiliza para realizar el reenvío.-(void)forwardInvocation:(NSInvocation*)anInvocationNSObject
Ejemplo
Aquí tenéis un ejemplo de un programa que demuestra los conceptos básicos del reenvío de correos electrónicos.
- Reenviador.h
#importar <objc/Object.h>@interface Forwarder : Object { id recipient ; // El objeto al que queremos reenviar el mensaje. }// Métodos de acceso. - ( id ) destinatario ; - ( id ) setRecipient: ( id ) _destinatario ; @end- Remitente.m
#importar "Forwarder.h"@implementation Forwarder - ( retval_t ) forward: ( SEL ) sel args: ( arglist_t ) args { /* * Comprueba si el destinatario realmente responde al mensaje. * Esto puede ser deseable o no; por ejemplo, si un destinatario * a su vez no responde al mensaje, podría reenviarlo * por sí mismo. */ if ([ recipient respondsToSelector : sel ]) { return [ recipient performv : sel args : args ]; } else { return [ self error : "El destinatario no responde" ]; } }- ( id ) setRecipient: ( id ) _recipient { [ recipient autorelease ]; recipient = [ _recipient retain ]; return self ; }- ( id ) destinatario { devolver destinatario ; } @end- Destinatario.h
#importar <objc/Object.h>// Un objeto Recipient simple. @interface Recipient : Object - ( id ) hello ; @end- Destinatario.m
#importar "Recipient.h"@destinatario de la implementación- ( id ) hola { printf ( "El destinatario dice hola! \n " );devolver self ; }@fin- main.m
#importar "Forwarder.h" #importar "Recipient.h"int main ( void ) { Forwarder * forwarder = [ Forwarder new ]; Recipient * recipient = [ Recipient new ];[ forwarder setRecipient : recipient ]; // Establecer el destinatario. /* * ¡Observe que forwarder no responde a un mensaje hello! Será * reenviado. Todos los métodos no reconocidos serán reenviados al * destinatario * (si el destinatario responde a ellos, como está escrito en Forwarder) */ [ forwarder hello ];[ liberación del destinatario ]; [ liberación del remitente ];devolver 0 ; }Notas
Cuando se compila usando gcc , el compilador informa:
$ gcc -x objective-c -Wno-import Forwarder.m Recipient.m main.m -lobjc main.m: En la función `main': main.m:12: advertencia: `Forwarder' no responde a `hello' $El compilador informa lo mencionado anteriormente: que Forwarderno responde a los mensajes hello. En este caso, se puede ignorar la advertencia, ya que se implementó el reenvío. Al ejecutar el programa se obtiene la siguiente salida:
$ ./a.out ¡ El destinatario dice hola!Categorías
Durante el diseño de Objective-C, una de las principales preocupaciones fue la mantenibilidad de grandes bases de código. La experiencia en el mundo de la programación estructurada había demostrado que una de las principales maneras de mejorar el código era dividirlo en partes más pequeñas. Inspirándose en los mixins del Common Lisp Object System , se desarrolló el concepto de categorías de Objective-C para facilitar este proceso. [ 30 ]
Las categorías permiten ampliar dinámicamente los métodos de una clase en tiempo de ejecución . Esto posibilitó que el programador utilizara clases abiertas sin necesidad de recompilar la clase ni siquiera tener acceso a su código fuente. Por ejemplo, si un sistema no incluye un corrector ortográfico en su implementación de String, este podría añadirse sin modificar el código fuente de String. [ 30 ]
Cuando se ejecuta el programa, los métodos dentro de las categorías se vuelven indistinguibles de los métodos de una clase. Una categoría tiene acceso completo a todas las variables de instancia dentro de la clase, incluidas las variables privadas.
Si una categoría declara un método con la misma firma que un método existente en una clase, se adopta el método de la categoría. Por lo tanto, las categorías no solo pueden agregar métodos a una clase, sino también reemplazar métodos existentes. Esta característica se puede usar para corregir errores en otras clases reescribiendo sus métodos, o para provocar un cambio global en el comportamiento de una clase dentro de un programa. Si dos categorías tienen métodos con el mismo nombre pero diferentes firmas, no se define qué método de la categoría se adopta.
Otros lenguajes han intentado incorporar esta funcionalidad de diversas maneras. TOM fue un paso más allá en el sistema Objective-C y permitió la adición de variables. Otros lenguajes han utilizado soluciones basadas en prototipos , siendo Self la más destacada .
Los lenguajes C# y Visual Basic (.NET) implementan funciones superficialmente similares en forma de métodos de extensión , [ 30 ] pero estos carecen de acceso a las variables privadas de la clase. [ 31 ] Ruby y otros lenguajes de programación dinámica se refieren a esta técnica como " monkey patching ".
Logtalk implementa un concepto de categorías (como entidades de primera clase) que engloba la función de categorías de Objective-C (las categorías de Logtalk también se pueden utilizar como unidades de composición de grano fino al definir, por ejemplo, nuevas clases o prototipos; en particular, una categoría de Logtalk puede ser importada virtualmente por cualquier número de clases y prototipos).
Ejemplo de uso de categorías
Este ejemplo crea una Integerclase, definiendo primero una clase básica con solo métodos de acceso implementados y agregando dos categorías, Arithmeticy Display, que extienden la clase básica. Si bien las categorías pueden acceder a los miembros de datos privados de la clase base, a menudo es una buena práctica acceder a estos miembros de datos privados a través de los métodos de acceso, lo que ayuda a mantener las categorías más independientes de la clase base. Implementar dichos accesores es un uso típico de las categorías. Otro es usar categorías para agregar métodos a la clase base. Sin embargo, no se considera una buena práctica usar categorías para sobrescribir subclases, también conocido como monkey patching . Los protocolos informales se implementan como una categoría en la NSObjectclase base. Por convención, los archivos que contienen categorías que extienden clases base tomarán el nombre BaseClass+ExtensionClass.h .
- Entero.h
#importar <objc/Object.h>@interface Integer : Object { int integer ; }- ( int ) entero ; - ( id ) entero: ( int ) _entero ; @end
- Entero.m
#importar "Integer.h"@implementation Integer - ( int ) integer { return integer ; }- ( id ) entero: ( int ) _entero { entero = _entero ; retornar self ; } @end
- Entero+Aritmética.h
#importar "Integer.h"@interface Entero (Aritmética) - ( id ) add: ( Entero * ) addend ; - ( id ) sub: ( Entero * ) subtrahend ; @end
- Entero+Aritmética.m
#importar "Integer+Arithmetic.h"@implementation Entero (Aritmética) - ( id ) add: ( Entero * ) addend { return [ self entero : [ self entero ] + [ addend entero ]]; }- ( id ) sub: ( Integer * ) sustraendo { return [ self entero : [ self entero ] - [ sustraendo entero ]]; } @end
- Entero+Display.h
#importar "Integer.h"@interface Entero (Display) - ( id ) showstars ; - ( id ) showint ; @end
- Entero+Display.m
# importar "Integer+Display.h"@implementation Integer (Display) - ( id ) showstars { int i , x = [ self integer ]; for ( i = 0 ; i < x ; i ++ ) { printf ( "*" ); } printf ( " \n " );devolver self ; }- ( id ) showint { printf ( "%d \n " , [ self integer ]);devolver self ; } @end
- main.m
#importar "Integer.h"#importar "Integer+Arithmetic.h"#importar "Integer+Display.h"int main ( void ) {Entero * num1 = [ Entero nuevo ], * num2 = [ Entero nuevo ];entero x ;printf ( "Ingrese un número entero: " );scanf ( "%d" , & x );[ num1 entero : x ];[ num1 estrellas del espectáculo ];printf ( "Ingrese un número entero: " );scanf ( "%d" , & x );[ num2 entero : x ];[ num2 estrellas del espectáculo ];[ num1 agregar : num2 ];[ num1 showint ];devolver 0 ;}
Notas
La compilación se realiza, por ejemplo, mediante:
$ gcc -x objective-c main.m Integer.m Integer+Arithmetic.m Integer+Display.m -lobjc Se puede experimentar omitiendo las #import "Integer+Arithmetic.h"líneas 2 y 21 durante la compilación. El programa seguirá funcionando. Esto significa que es posible combinar categorías añadidas según sea necesario; si una categoría no requiere alguna funcionalidad, simplemente no se puede compilar.[num1add:num2]Integer+Arithmetic.m
Posando
Objective-C permite que una clase reemplace por completo a otra dentro de un programa. Se dice que la clase que reemplaza "se hace pasar" por la clase objetivo.
La función de posicionamiento de clases se declaró obsoleta con Mac OS X v10.5 y no está disponible en el entorno de ejecución de 64 bits . Se puede lograr una función similar utilizando la técnica de intercambio de métodos en categorías, que consiste en intercambiar la implementación de un método con la de otro que tenga la misma firma.
Para las versiones que aún admiten el posicionamiento, todos los mensajes enviados a la clase de destino son recibidos por la clase de posicionamiento. Existen varias restricciones:
- Una clase solo puede presentarse como una de sus superclases directas o indirectas.
- La clase que realiza la solicitud no debe definir ninguna variable de instancia nueva que no esté presente en la clase de destino (aunque puede definir o sobrescribir métodos).
- Es posible que la clase objetivo no haya recibido ningún mensaje antes de la solicitud.
El posado, al igual que las categorías, permite una ampliación global de las clases existentes. El posado permite dos características ausentes en las categorías:
- Una clase que realiza la operación puede llamar a métodos sobrescritos a través de super, incorporando así la implementación de la clase de destino.
- Una clase de pose puede sobrescribir los métodos definidos en las categorías.
Por ejemplo,
@interface CustomNSApplication : NSApplication @end@implementation CustomNSApplication - ( void ) setMainMenu: ( NSMenu * ) menu { // hacer algo con menu } @endclass_poseAs ([ Clase CustomNSApplication ], [ Clase NSApplication ]);Esto intercepta cada invocación de setMainMenu a NSApplication.
#importar
En el lenguaje C, la #includedirectiva pre-compile siempre hace que el contenido de un archivo se inserte en el código fuente en ese punto. Objective-C tiene la #importdirectiva, equivalente excepto que cada archivo se incluye solo una vez por unidad de compilación, lo que elimina la necesidad de protecciones de inclusión .
La directiva Objective-C no debe confundirse con la palabra clave de C++ , que se utiliza para importar módulosimport de C++ (desde C++20 ) y no es una directiva de preprocesador. Tampoco debe confundirse con la directiva de preprocesador en Microsoft Visual C++ (MSVC), que no es estándar y se utiliza para importar bibliotecas de tipos. [ 32 ]#import
Compilación de Linux gcc
// ARCHIVO: hello.m #import <Foundation/Foundation.h> int main ( int argc , const char * argv []) { /* mi primer programa en Objective-C */ NSLog ( @"¡Hola, mundo! \n " ); return 0 ; }$ # Compilar la línea de comandos para gcc y el compilador MinGW: $ gcc \ $ ( gnustep-config --objc-flags ) \ -o hello \ hello.m \ -L /GNUstep/System/Library/Libraries \ -lobjc \ -lgnustep-base$ ./hola Otras características
Las características de Objective-C a menudo permiten soluciones flexibles y, con frecuencia, sencillas a los problemas de programación.
- La delegación de métodos a otros objetos y la invocación remota se pueden implementar fácilmente utilizando categorías y reenvío de mensajes.
- La modificación del puntero isa permite que las clases cambien en tiempo de ejecución. Se utiliza normalmente para la depuración, donde los objetos liberados se convierten en objetos zombie cuyo único propósito es informar de un error cuando alguien los llama. La modificación también se utilizó en Enterprise Objects Framework para crear fallos en la base de datos. Actualmente, Foundation Framework de Apple utiliza la modificación para implementar la observación de clave-valor .
Revisiones importantes
Objective-C 2.0
En la Conferencia Mundial de Desarrolladores de 2006 , Apple anunció el lanzamiento de "Objective-C 2.0", una revisión del lenguaje Objective-C que incluía "recolección de basura moderna, mejoras de sintaxis, [ 33 ] mejoras de rendimiento en tiempo de ejecución, [ 34 ] y compatibilidad con 64 bits". Mac OS X v10.5 , lanzado en octubre de 2007, incluía un compilador Objective-C 2.0. GCC 4.6 admite muchas características nuevas de Objective-C, como propiedades declaradas y sintetizadas, sintaxis de punto, enumeración rápida, métodos de protocolo opcionales, atributos de método/protocolo/clase, extensiones de clase y una nueva API de tiempo de ejecución de GNU Objective-C. [ 35 ]
La denominación Objective-C 2.0 representa una ruptura en el sistema de versiones del lenguaje, ya que la última versión de Objective-C para NeXT fue "objc4". [ 36 ] Este nombre de proyecto se mantuvo en la última versión del código fuente del entorno de ejecución de Objective-C heredado en Mac OS X Leopard (10.5). [ 37 ]
Recogida de basura
Objective-C 2.0 proporcionaba un recolector de basura generacional conservador opcional . Cuando se ejecutaba en modo retrocompatible , el entorno de ejecución convertía las operaciones de conteo de referencias , como "retain" y "release", en operaciones nulas . Todos los objetos estaban sujetos a la recolección de basura cuando esta estaba habilitada. Los punteros C regulares podían calificarse con "__strong" para activar también las intercepciones del compilador de barrera de escritura subyacentes y, por lo tanto, participar en la recolección de basura. [ 38 ] También se proporcionaba un subsistema débil de puesta a cero, de modo que los punteros marcados como "__weak" se establecían a cero cuando se recolectaba el objeto (o, más simplemente, la memoria GC). El recolector de basura no existe en la implementación de Objective-C 2.0 para iOS. [ 39 ] La recolección de basura en Objective-C se ejecuta en un hilo en segundo plano de baja prioridad y puede detenerse ante eventos del usuario, con la intención de mantener la experiencia del usuario receptiva. [ 40 ]
La recolección de basura quedó obsoleta en Mac OS X v10.8 en favor del conteo automático de referencias (ARC). [ 41 ] Objective-C en iOS 7 ejecutándose en ARM64 usa 19 bits de una palabra de 64 bits para almacenar el conteo de referencias, como una forma de punteros etiquetados . [ 42 ] [ 43 ]
Propiedades
Objective-C 2.0 introduce una nueva sintaxis para declarar variables de instancia como propiedades , con atributos opcionales para configurar la generación de métodos de acceso. Las propiedades son, en cierto sentido, variables de instancia públicas; es decir, declarar una variable de instancia como propiedad proporciona a las clases externas acceso (posiblemente limitado, por ejemplo, de solo lectura) a esa propiedad. Una propiedad puede declararse como "de solo lectura" y puede proporcionarse con semántica de almacenamiento como assigno copy. retainPor defecto, las propiedades se consideran atomic, lo que resulta en un bloqueo que impide que varios subprocesos accedan a ellas al mismo tiempo. Una propiedad puede declararse como nonatomic, lo que elimina este bloqueo.
@interface Person : NSObject { @public NSString * name ; @private int age ; }@property ( copia ) NSString * nombre ; @property ( solo lectura ) int edad ;- ( id ) initWithAge: ( int ) age ; @endLas propiedades se implementan mediante la @synthesizepalabra clave, que genera métodos getter (y setter, si no son de solo lectura) según la declaración de la propiedad. Alternativamente, los métodos getter y setter deben implementarse explícitamente, o @dynamicse puede usar la palabra clave para indicar que los métodos de acceso se proporcionarán por otros medios. Cuando se compila con clang 3.1 o superior, todas las propiedades que no se declaran explícitamente con @dynamic, están marcadas readonlyo tienen getter y setter completos implementados por el usuario se @synthesize'd automáticamente de forma implícita.
@implementación Persona @sintetizar nombre ;- ( id ) initWithAge: ( int ) initAge { self = [ super init ]; if ( self ) { // NOTA: asignación directa de variable de instancia, no setter de propiedad age = initAge ; } return self ; }- ( int ) edad { return edad ; } @endSe puede acceder a las propiedades utilizando la sintaxis tradicional de paso de mensajes, la notación de puntos o, en la codificación clave-valor, por nombre a través de los métodos "valueForKey:"/"setValue:forKey:".
Persona * aPersona = [[ Persona alloc ] initWithAge : 53 ]; aPersona . nombre = @"Steve" ; // NOTA: notación de punto, usa setter sintetizado, // equivalente a [aPersona setName: @"Steve"]; NSLog ( @"Acceso por mensaje (%@), notación de punto (%@), nombre de propiedad (% @) y " "acceso directo a variable de instancia (% @) " , [ aPersona nombre ], aPersona . nombre , [ aPersona valueForKey : @"nombre" ], aPersona -> nombre );Para usar la notación de punto para invocar accesores de propiedades dentro de un método de instancia, selfse debe usar la palabra clave:
- ( void ) introduceMyselfWithProperties: ( BOOL ) useGetter { NSLog ( @"Hola, mi nombre es %@." , ( useGetter ? self . name : name )); // NOTA: acceso mediante getter vs. ivar }Las propiedades de una clase o protocolo pueden ser inspeccionadas dinámicamente .
int i ; int propertyCount = 0 ; objc_property_t * propertyList = class_copyPropertyList ([ aPerson class ], & propertyCount );for ( i = 0 ; i < propertyCount ; i ++ ) { objc_property_t * thisProperty = propertyList + i ; const char * propertyName = property_getName ( * thisProperty ); NSLog ( @"La persona tiene una propiedad: '%s'" , propertyName ); }Variables de instancia no frágiles
Objective-C 2.0 proporciona variables de instancia no frágiles cuando el entorno de ejecución lo admite (es decir, al compilar código para macOS de 64 bits y todas las versiones de iOS). En el entorno de ejecución moderno, se agrega una capa adicional de indirección al acceso a las variables de instancia, lo que permite al enlazador dinámico ajustar la disposición de la instancia en tiempo de ejecución. Esta característica permite dos mejoras importantes en el código Objective-C:
- Elimina el problema de la interfaz binaria frágil ; las superclases pueden cambiar de tamaño sin afectar la compatibilidad binaria.
- Permite que las variables de instancia que proporcionan la base para las propiedades se sinteticen en tiempo de ejecución sin necesidad de declararlas en la interfaz de la clase.
enumeración rápida
En lugar de usar un objeto NSEnumerator o índices para iterar sobre una colección, Objective-C 2.0 ofrece la sintaxis de enumeración rápida. En Objective-C 2.0, los siguientes bucles son funcionalmente equivalentes, pero presentan características de rendimiento diferentes.
// Usando NSEnumerator NSEnumerator * enumerator = [ thePeople objectEnumerator ]; Person * p ;while (( p = [ enumerator nextObject ]) != nil ) { NSLog ( @"%@ tiene %i años." , [ p nombre ], [ p edad ]); }// Usando índices for ( int i = 0 ; i < [ thePeople count ]; i ++ ) { Person * p = [ thePeople objectAtIndex : i ]; NSLog ( @"%@ tiene %i años." , [ p name ], [ p age ]); }// Usando enumeración rápida for ( Person * p in thePeople ) { NSLog ( @"%@ tiene %i años." , [ p nombre ], [ p edad ]); }La enumeración rápida genera código más eficiente que la enumeración estándar porque las llamadas a métodos para enumerar objetos se reemplazan por aritmética de punteros utilizando el protocolo NSFastEnumeration. [ 44 ]
NSFastEnumeration no está presente en Mac OS X versión 10.4 o anterior. Los binarios compilados para usar esta función no se ejecutarán en estas versiones anteriores de Mac OS X.
Extensiones de clase
Una extensión de clase tiene la misma sintaxis que una declaración de categoría sin nombre de categoría, y los métodos y propiedades declarados en ella se agregan directamente a la clase principal. Se utiliza principalmente como alternativa a una categoría para agregar métodos a una clase sin anunciarlos en los encabezados públicos, con la ventaja de que, para las extensiones de clase, el compilador verifica que todos los métodos declarados privadamente estén realmente implementados. [ 45 ]
Bloques
Blocks es una extensión para Objective-C (y C y C++ ) que utiliza una sintaxis especial para crear cierres . Blocks solo es compatible con Mac OS X 10.6 "Snow Leopard" o posterior, iOS 4 o posterior, y GNUstep con libobjc2 1.7 y compilando con clang 3.1 o posterior. [ 46 ]
#include <stdio.h> #include <Block.h> typedef int ( ^ IntBlock )();IntBlock MakeCounter ( int start , int increment ) { __block int i = start ;return Block_copy ( ^ { int ret = i ; i += increment ; return ret ; });}int main ( void ) { IntBlock mycounter = MakeCounter ( 5 , 2 ); printf ( "Primera llamada: %d \n " , mycounter ()); printf ( "Segunda llamada: %d \n " , mycounter ()); printf ( "Tercera llamada: %d \n " , mycounter ());/* porque fue copiado, también debe ser liberado */ Block_release ( mycounter );return 0 ; } /* Salida: Primera llamada: 5 Segunda llamada: 7 Tercera llamada: 9 */Objetivo C moderno
Apple ha añadido algunas características adicionales a Objective 2.0 con el tiempo. Apple describe estos cambios como aplicables únicamente al " compilador LLVM de Apple " (clang), pero también se encuentran en versiones de código abierto de clang. Resulta confuso que el sistema de versiones utilizado por Apple difiera del de LLVM; consulte Xcode § Versiones de la cadena de herramientas para obtener una traducción a los números de versión de LLVM de código abierto. [ 47 ]
Conteo automático de referencias
El conteo automático de referencias (ARC) es una característica de tiempo de compilación que elimina la necesidad de que los programadores administren manualmente los conteos de retención usando retainy release. [ 48 ] A diferencia de la recolección de basura , que ocurre en tiempo de ejecución, ARC elimina la sobrecarga de un proceso separado que administra los conteos de retención. ARC y la administración manual de memoria no son mutuamente excluyentes; los programadores pueden continuar usando código sin ARC en proyectos habilitados para ARC deshabilitando ARC para archivos de código individuales. Xcode también puede intentar actualizar automáticamente un proyecto a ARC.
ARC se introdujo en LLVM 3.0. Esto se traduce en Xcode 4.2 (2011) o en el compilador LLVM 3.0 de Apple. [ 49 ]
Literales
Los entornos de ejecución de NeXT y Apple Obj-C incluyen desde hace tiempo una forma abreviada de crear nuevas cadenas, utilizando la sintaxis literal @"a new string", o bien recurriendo a las constantes de CoreFoundation kCFBooleanTruey kCFBooleanFalsea NSNumberlos valores booleanos. El uso de este formato evita que el programador tenga que utilizar initWithString:métodos más largos o similares al realizar ciertas operaciones.
Al usar el compilador Apple LLVM 4.0 (Xcode 4.4) o posterior, las matrices, los diccionarios y los números ( clases NSArray, NSDictionary, NSNumber) también se pueden crear usando sintaxis literal en lugar de métodos. [ 50 ] (El compilador Apple LLVM 4.0 se traduce a LLVM de código abierto y Clang 3.1.) [ 51 ]
Ejemplo sin literales:
NSArray * myArray = [ NSArray arrayWithObjects : object1 , object2 , object3 , nil ]; NSDictionary * myDictionary1 = [ NSDictionary dictionaryWithObject : someObject forKey : @"key" ]; NSDictionary * myDictionary2 = [ NSDictionary dictionaryWithObjectsAndKeys : object1 , key1 , object2 , key2 , nil ]; NSNumber * myNumber = [ NSNumber numberWithInt : myInt ]; NSNumber * mySumNumber = [ NSNumber numberWithInt : ( 2 + 3 )]; NSNumber * myBoolNumber = [ NSNumber numberWithBool : YES ];Ejemplo con literales:
NSArray * myArray = @[ object1 , object2 , object3 ] ; NSDictionary * myDictionary1 = @{ @"key" : someObject } ; NSDictionary * myDictionary2 = @{ key1 : object1 , key2 : object2 } ; NSNumber * myNumber = @( myInt ) ; NSNumber * mySumNumber = @( 2 + 3 ) ; NSNumber * myBoolNumber = @YES ; NSNumber * myIntegerNumber = @8 ;En las versiones de Xcode anteriores a la 13, a diferencia de los literales de cadena, los literales de matriz, diccionario y número se compilaban en código equivalente a las llamadas a métodos mencionadas anteriormente. En particular, bajo la administración de memoria con conteo de referencias manual, estos objetos se liberaban automáticamente, lo que requería especial cuidado cuando, por ejemplo, se usaban con variables estáticas de función u otro tipo de variables globales.
En Xcode 13 (versión de clang 13.0.0 [ 52 ] ) y posteriores, los literales de matriz, diccionario y número también pueden incrustarse en el binario en tiempo de compilación, al igual que los literales de cadena. Esta característica está habilitada de forma predeterminada en las plataformas de Apple y puede controlarse con las -fno-objc-constant-literalsbanderas del compilador relacionadas. [ 53 ]
Subíndice
Al usar el compilador Apple LLVM 4.0 o posterior, los arreglos y diccionarios ( NSArrayy NSDictionaryclases) se pueden manipular mediante la indexación. [ 50 ] La indexación se puede usar para recuperar valores de índices (arreglos) o claves (diccionarios), y con objetos mutables, también se puede usar para asignar objetos a índices o claves. En el código, la indexación se representa mediante corchetes [ ]. [ 54 ]
Ejemplo sin índices:
id objeto1 = [ someArray objetoEnÍndice : 0 ]; id objeto2 = [ someDictionary objetoParaClave : @"clave" ]; [ someMutableArray reemplazarObjetoEnÍndice : 0 conObjeto : objeto3 ]; [ someMutableDictionary establecerObjeto : objeto4 paraClave : @"clave" ];Ejemplo con subíndices:
id objeto1 = someArray [ 0 ]; id objeto2 = someDictionary [ @"key" ]; someMutableArray [ 0 ] = objeto3 ; someMutableDictionary [ @"key" ] = objeto4 ;Variantes lingüísticas
Objective-C++
Objective-C++ es una variante de lenguaje aceptada por el front-end de GNU Compiler Collection y Clang , que puede compilar archivos fuente que utilizan una combinación de sintaxis de C++ y Objective-C. Fue desarrollado por NeXT a petición de Lotus Development durante el desarrollo del programa de hoja de cálculo Improv en 1989. [ 55 ] El término "Objective-C++" también apareció en la documentación de Apple para su compilador Objective-C, pero posteriormente fue eliminado. [ 56 ]
Objective-C++ añade a C++ las extensiones que Objective-C añade a C. Como no se hace nada para unificar la semántica de las distintas características del lenguaje, se aplican ciertas restricciones:
- Una clase de C++ no puede heredar de una clase de Objective-C y viceversa. [ 55 ]
- Los espacios de nombres de C++ no se pueden declarar dentro de una declaración de Objective-C.
- Las declaraciones de Objective-C solo pueden aparecer en el ámbito global, no dentro de un espacio de nombres de C++.
- Las clases de Objective-C no pueden tener variables de instancia de clases de C++ que carezcan de un constructor predeterminado o que tengan uno o más métodos virtuales , pero los punteros a objetos de C++ se pueden usar como variables de instancia sin restricciones (asígnelos con new en el método -init).
- La semántica "por valor" de C++ no se puede aplicar a los objetos de Objective-C, que solo son accesibles a través de punteros.
- Una declaración de Objective-C no puede estar dentro de una declaración de plantilla de C++ y viceversa. Sin embargo, los tipos de Objective-C (por ejemplo,
Classname *) pueden usarse como parámetros de plantilla de C++. - El manejo de excepciones en Objective-C y C++ es distinto; los manejadores de cada uno no pueden manejar excepciones del otro tipo. Como resultado, los destructores de objetos no se ejecutan. Esto se mitiga en las versiones recientes de "Objective-C 2.0" , ya que las excepciones de Objective-C se reemplazan completamente por excepciones de C++ (entorno de ejecución de Apple) o parcialmente cuando se enlaza la biblioteca de Objective-C++ ( GNUStep libobjc2). [ 56 ]
- Los bloques de Objective-C y las expresiones lambda de C++11 son entidades distintas. Sin embargo, en macOS se genera un bloque de forma transparente al pasar una expresión lambda donde se espera un bloque. [ 57 ]
Sintaxis "moderna" de Objective-C (1997)
Tras la compra de NeXT por parte de Apple, se intentó que el lenguaje resultara más aceptable para programadores más familiarizados con Java que con Smalltalk. Uno de estos intentos fue la introducción de lo que en aquel momento se denominó "Sintaxis Moderna" para Objective-C [ 58 ] (en contraste con la sintaxis "clásica" actual). No hubo ningún cambio en el comportamiento; se trataba simplemente de una sintaxis alternativa. En lugar de escribir una invocación de método como:
objeto = [[ MyClass alloc ] init ]; [ objeto firstLabel : param1 secondLabel : param2 ];En cambio, fue escrito como
objeto = ( MyClass . alloc ). init ; objeto . labels ( param1 , param2 );De manera similar, las declaraciones pasaron de la forma
- ( void ) firstLabel : ( int ) param1 secondLabel : ( int ) param2 ;a
- ( void ) etiquetas ( int param1 , int param2 );Esta sintaxis "moderna" ya no es compatible con las variantes actuales del lenguaje Objective-C.
Implementaciones
Objective-C fue implementado originalmente por un compilador propietario de PPI/StepStone (ver Historial más arriba). NeXT implementó Objective-C modificando GCC , lo que permitió el uso de características más recientes de C. Apple mantuvo la situación durante un tiempo después de su compra de NeXT, dando lugar a Apple GCC y Apple LLVM-GCC, ambos dejaron de recibir actualizaciones en la versión 4.2.1 debido a que GCC cambió su licencia a GPLv3, que contiene una disposición contra la Tivoización . [ 36 ] : En cuanto al entorno de ejecución, Apple decidió construirlo sobre el compilador clang de LLVM desde aproximadamente 2009, que tiene una licencia mucho más permisiva. Apple contribuye con cambios relacionados con Objective-C a LLVM, convirtiéndolo en la implementación de código abierto más completa a partir de 2026.
GNU, GNUstep y WinObjC
El proyecto GNU ha estado interesado durante mucho tiempo en una plataforma para portar programas NeXT y Obj-C. El registro de cambios del directorio libobjc en GCC sugiere que existía antes de 1998 (GCC 2.95), y su archivo README indica además una reescritura en 1993 (GCC 2.4). [ 59 ]
El código fuente del frontend de NeXT se publicó ya que se creó como parte de GCC, publicado bajo la Licencia Pública General de GNU, que obliga a quienes crean obras derivadas a hacerlo. Apple continuó esta tradición publicando su bifurcación de GCC hasta la versión 4.2.1, después de la cual abandonaron el compilador. Los mantenedores de GCC tomaron en cuenta los cambios, pero no invirtieron mucho en dar soporte a características más recientes como el lenguaje Objective-C 2.0. [ 36 ] : ¿Qué compilador?
Los desarrolladores de GNUstep, interesados en el nuevo lenguaje, bifurcaron la biblioteca libobjc de GCC en un proyecto independiente de GCC llamado libobjc2 en 2009. También dispusieron que el entorno de ejecución se utilizara con Clang para aprovechar la nueva sintaxis del lenguaje. [ 36 ] : ¿Qué compilador ? GCC avanzó lentamente al mismo tiempo, pero en GCC 4.6.0 (2011) también pasaron a Objective-C 2.0 en su libobjc. [ 35 ] [ 60 ] La documentación de GNUstep sugiere que la implementación de GCC todavía carece de soporte para bloques, variables no frágiles y el ARC más reciente. [ 36 ] : ¿Qué entorno de ejecución?
Microsoft bifurcó el entorno de ejecución de ObjFW en una parte de WinObjC , el puente de iOS para la Plataforma Universal de Windows , en 2015, aunque cambió a una bifurcación de libobjc2 en 2016. Combinado con su propia implementación de Cocoa Touch y las API subyacentes, el proyecto permite la reutilización del código de las aplicaciones de iOS dentro de las aplicaciones UWP. [ 61 ]
En Windows, las herramientas de desarrollo de Objective-C están disponibles para su descarga en el sitio web de GNUStep. El sistema de desarrollo de GNUStep consta de los siguientes paquetes: GNUstep MSYS System, GNUstep Core, GNUstep Devel, GNUstep Cairo, ProjectCenter IDE (similar a Xcode, pero menos complejo) y Gorm (generador de interfaces similar al generador de NIB de Xcode). Estos instaladores binarios no se han actualizado desde 2016, [ 62 ] por lo que podría ser mejor instalarlos compilando con Cygwin o MSYS2 .
Sonido metálico
El conjunto de compiladores Clang , parte del proyecto LLVM , implementa Objective-C y otros lenguajes. Después de que GCC 4.3 (2008) adoptara la licencia GPLv3, Apple lo abandonó en favor de Clang, un compilador que tiene mayor libertad legal para modificar. Como resultado, muchas de las características modernas del lenguaje Objective-C solo son compatibles con Clang. [ 47 ]
El esquema de versiones de Apple para su compilador LLVM basado en clang difiere del esquema de versiones de código abierto de LLVM. Consulte Xcode § Versiones de la cadena de herramientas para obtener una traducción. [ 47 ]
mulle-objc
mulle-objc es una implementación de Objective-C orientada al rendimiento. Utiliza una biblioteca de tiempo de ejecución escrita en C11 puro , lo que garantiza la portabilidad (entre otras plataformas, admite Linux, FreeBSD y Windows). La biblioteca de tiempo de ejecución se puede enlazar estáticamente con musl . Utiliza una bifurcación de clang/LLVM como compilador y una bifurcación de gdb como depurador. [ 63 ] [ 64 ] Mulle-objc tiene un conjunto de características intencionalmente reducido, que se describe mejor como "Objective-C 1.0 con algunas características 2.0 seleccionadas". [ 65 ]
Compilador de objetos portátil
El Portable Object Compiler (POC) era una implementación alternativa de Objective-C. El conjunto de extensiones implementadas por el POC difiere de la implementación de GCC/NeXT/Apple; en particular, incluye bloques similares a Smalltalk para Objective-C, mientras que carece de protocolos y categorías, dos características ampliamente utilizadas en OpenStep y sus derivados y parientes. En general, el POC representa una etapa anterior, previa a NeXT, en la evolución del lenguaje, que se ajusta aproximadamente al libro de Brad Cox de 1991. [ 66 ]
También incluye una biblioteca de tiempo de ejecución llamada ObjectPak, que se basa en la biblioteca original ICPak101 de Cox (que a su vez deriva de la biblioteca de clases Smalltalk-80) y es radicalmente diferente de OpenStep FoundationKit.
Uso de la biblioteca
Actualmente, Objective-C se utiliza a menudo junto con una biblioteca fija de objetos estándar (conocida comúnmente como "kit" o "framework"), como Cocoa , GNUstep u ObjFW . Estas bibliotecas suelen venir incluidas con el sistema operativo: las bibliotecas de GNUstep suelen venir con las distribuciones basadas en Linux y Cocoa con macOS. El programador no está obligado a heredar funciones de la clase base existente (NSObject – OFObject). Objective-C permite la declaración de nuevas clases raíz que no heredan ninguna función existente. Originalmente, los entornos de programación basados en Objective-C solían ofrecer una clase Object como clase base de la que heredaban casi todas las demás clases. Con la introducción de OpenStep, NeXT creó una nueva clase base llamada NSObject, que ofrecía características adicionales respecto a Object (por ejemplo, un énfasis en el uso de referencias a objetos y conteo de referencias en lugar de punteros sin formato). Casi todas las clases en Cocoa heredan de NSObject.
El cambio de nombre no solo sirvió para diferenciar el nuevo comportamiento predeterminado de las clases dentro de la API de OpenStep, sino que también permitió que el código que utilizaba Object —la clase base original utilizada en NeXTSTEP (y, en mayor o menor medida, en otras bibliotecas de clases de Objective-C)— coexistiera en el mismo entorno de ejecución con el código que utilizaba NSObject (con algunas limitaciones). La introducción del prefijo de dos letras también se convirtió en una forma simplificada de espacios de nombres, de los que carece Objective-C. El uso de un prefijo para crear un identificador de empaquetado informal se convirtió en un estándar de codificación informal en la comunidad de Objective-C, y continúa vigente hasta el día de hoy.
Más recientemente, han comenzado a aparecer gestores de paquetes, como CocoaPods , que pretende ser tanto un gestor de paquetes como un repositorio de paquetes. Gran parte del código Objective-C de código abierto escrito en los últimos años ahora se puede instalar usando CocoaPods.
Análisis del lenguaje
Las implementaciones de Objective-C utilizan un sistema de ejecución ligero escrito en C , lo que apenas aumenta el tamaño de la aplicación. En contraste, la mayoría de los sistemas orientados a objetos de la época en que se creó utilizaban grandes máquinas virtuales . Los programas escritos en Objective-C tienden a ser poco más grandes que el tamaño de su código y el de las bibliotecas (que generalmente no necesitan incluirse en la distribución del software), a diferencia de los sistemas Smalltalk, donde se utilizaba una gran cantidad de memoria solo para abrir una ventana. Las aplicaciones de Objective-C tienden a ser más grandes que aplicaciones similares en C o C++ porque el tipado dinámico de Objective-C no permite eliminar ni insertar métodos. Dado que el programador tiene tanta libertad para delegar, reenviar llamadas, construir selectores sobre la marcha y pasarlos al sistema de ejecución, el compilador de Objective-C no puede asumir que es seguro eliminar métodos no utilizados o insertar llamadas.
Asimismo, el lenguaje puede implementarse sobre compiladores C existentes (en GCC , primero como preprocesador y luego como módulo) en lugar de como un compilador nuevo. Esto permite a Objective-C aprovechar la enorme colección existente de código, bibliotecas, herramientas, etc., de C. Las bibliotecas C existentes pueden integrarse en Objective-C para proporcionar una interfaz orientada a objetos. En este sentido, es similar a la biblioteca GObject y al lenguaje Vala , ampliamente utilizados en el desarrollo de aplicaciones GTK .
Todos estos cambios prácticos redujeron las barreras de entrada , que probablemente fueron el mayor problema para la aceptación generalizada de Smalltalk en la década de 1980.
Una crítica común es que Objective-C no admite espacios de nombres . En su lugar, los programadores se ven obligados a añadir prefijos a los nombres de sus clases, que tradicionalmente son más cortos que los nombres de los espacios de nombres y, por lo tanto, más propensos a colisiones. Desde 2007, todas las clases y funciones de macOS en el entorno de programación Cocoa llevan el prefijo "NS" (por ejemplo, NSObject, NSButton) para identificarlas como pertenecientes al núcleo de macOS o iOS; el prefijo "NS" deriva de los nombres de las clases tal como se definieron durante el desarrollo de NeXTSTEP .
Dado que Objective-C es un superconjunto estricto de C, no trata los tipos primitivos de C como objetos de primera clase .
A diferencia de C++ , Objective-C no admite la sobrecarga de operadores . Asimismo, a diferencia de C++, Objective-C permite que un objeto herede directamente de una sola clase (prohibiendo la herencia múltiple ). Sin embargo, en la mayoría de los casos, se pueden utilizar categorías y protocolos como alternativas para lograr los mismos resultados.
Debido a que Objective-C utiliza tipado dinámico en tiempo de ejecución y a que todas las llamadas a métodos son llamadas a funciones (o, en algunos casos, llamadas al sistema), muchas optimizaciones de rendimiento comunes no se pueden aplicar a los métodos de Objective-C (por ejemplo: inserción de código en línea, propagación de constantes, optimizaciones interprocedimentales y reemplazo escalar de agregados). Esto limita el rendimiento de las abstracciones de Objective-C en comparación con abstracciones similares en lenguajes como C++, donde dichas optimizaciones son posibles.
Gestión de la memoria
Las primeras versiones de Objective-C no admitían la recolección de basura (GC). En aquel entonces, esta decisión generó cierto debate, y muchos consideraban que los largos periodos de inactividad (cuando Smalltalk realizaba la recolección) hacían que todo el sistema fuera inutilizable. Algunas implementaciones de terceros han añadido esta función, en particular GNUstep, que utiliza el recolector de basura Boehm .
Apple implementó GC como parte de Objective-C 2.0 a partir de Mac OS X v10.5 . [ 67 ] La nueva característica resultó impopular entre los desarrolladores; Apple no convirtió ninguna de sus aplicaciones internas para usar GC, aparte de Xcode . [ 17 ] La adopción se vio gravemente obstaculizada por el hecho de que GC no se hizo disponible en el iPhone debido a preocupaciones sobre el rendimiento del software . [ 17 ] [ 67 ] En versiones más recientes de macOS, la recolección de basura ha sido obsoleta en favor del Conteo Automático de Referencias (ARC), introducido en 2011. [ 17 ]
Con ARC, el compilador inserta automáticamente llamadas a retain y release en el código Objective-C basándose en el análisis estático del código . Esta automatización libera al programador de la necesidad de escribir código para la gestión de memoria. ARC también añade referencias débiles al lenguaje Objective-C. [ 68 ] [ 69 ]
Diferencias filosóficas entre Objective-C y C++
El diseño y la implementación de C++ y Objective-C representan enfoques fundamentalmente diferentes para extender C.
Además del estilo de programación procedimental de C, C++ admite directamente ciertas formas de programación orientada a objetos , programación genérica y metaprogramación . C++ también incluye una amplia biblioteca estándar con varias clases contenedoras . De manera similar, Objective-C añade programación orientada a objetos , tipado dinámico y reflexión a C. Objective-C no proporciona una biblioteca estándar propiamente dicha , pero en la mayoría de los casos donde se utiliza, se combina con una biblioteca similar a OpenStep , como OPENSTEP , Cocoa o GNUstep , que ofrece funciones parecidas a las de la biblioteca estándar de C++.
Una diferencia notable es que Objective-C ofrece soporte en tiempo de ejecución para funciones de programación reflexiva , mientras que C++ solo añade un soporte limitado a C. En Objective-C, se puede consultar sobre las propiedades de un objeto, por ejemplo, si responderá a un mensaje determinado. En C++, esto no es posible sin el uso de bibliotecas externas.
El uso de la reflexión forma parte de la distinción más amplia entre las características dinámicas (de tiempo de ejecución) y estáticas (de tiempo de compilación) de un lenguaje. Si bien Objective-C y C++ emplean una combinación de ambas, Objective-C prioriza las decisiones de tiempo de ejecución, mientras que C++ las prioriza de tiempo de compilación. La tensión entre la programación dinámica y estática implica muchas de las disyuntivas clásicas de la programación: las características dinámicas aportan flexibilidad, mientras que las estáticas aportan velocidad y verificación de tipos.
La programación genérica y la metaprogramación pueden implementarse en ambos lenguajes mediante polimorfismo en tiempo de ejecución ( despacho dinámico ). En C++, esto se manifiesta en forma de funciones virtuales e identificación de tipos en tiempo de ejecución , mientras que Objective-C ofrece tipado dinámico y reflexión. Tanto Objective-C como C++ admiten polimorfismo en tiempo de compilación ( funciones genéricas ), característica que Objective-C incorporó en 2015.
Véase también
- C (lenguaje de programación)
- C++
- Cápsulas de cacao
- Comparación de lenguajes de programación
- GNUStep
- Comparación con COM, GObject, SOM, Windows Runtime, XPCOM
- Swift (lenguaje de programación)
- Xcode
- WinObjC (también conocido como: Windows Bridge para iOS)
Referencias
Citas
- ↑ "Versiones y plataformas de tiempo de ejecución" . Developer.apple.com . Archivado del original el 20 de julio de 2016. Consultado el 24 de diciembre de 2017 .
- ↑ Lattner, Chris (3 de junio de 2014). "Página principal de Chris Lattner" . Chris Lattner. Archivado del original el 4 de junio de 2014. Recuperado el 3 de junio de 2014. El
lenguaje Swift es el producto del esfuerzo incansable de un equipo de expertos en lenguajes, gurús de la documentación, ninjas de la optimización de compiladores y un grupo interno de pruebas increíblemente importante que proporcionó retroalimentación para ayudar a refinar y probar ideas. Por supuesto, también se benefició enormemente de las experiencias ganadas con esfuerzo por muchos otros lenguajes en el campo, tomando ideas de Objective-C, Rust,
Haskell
,
Ruby
,
Python
,
C#
, CLU y demasiados otros para enumerar.
- ↑ Apple Developer (23 de abril de 2013). "El lenguaje de programación Objective-C (Introducción)" . Apple Inc. Archivado del original el 26 de octubre de 2018. Consultado el 15 de febrero de 2025 .
- ↑ Singh, Amit (diciembre de 2003). "Una breve historia de Mac OS X" . Mac OS X Internals. Archivado del original el 14 de mayo de 2012. Recuperado el 11 de junio de 2012 .
- ↑ "App Frameworks" . Apple. Junio de 2014. Archivado del original el 16 de febrero de 2019. Consultado el 13 de febrero de 2019 .
- ↑ Cox, Naroff y Hsu (2020) , pág. 2.
- ↑ Garling, Caleb (9 de julio de 2012). "El lenguaje de programación del iPhone es ahora el tercero más popular del mundo" . Wired . Archivado del original el 9 de septiembre de 2013. Consultado el 27 de abril de 2026 .
- ↑ Wentk, Richard (2009). Cocoa: Volumen 5 de la serie de referencia para desarrolladores de Apple . John Wiley and Sons. ISBN 978-0-470-49589-6. Consultado el 22 de julio de 2016 .
- ↑ Biancuzzi, F.; Warden, S. (2009). "Objective-C". Masterminds of Programming . O'Reilly Media, Inc. pp. 242–246 . ISBN 978-0-596-51517-1.
- ↑ Cox, Brad (1983). "El precompilador orientado a objetos: programación de métodos Smalltalk-80 en lenguaje C" . ACM SIGPLAN Notices . 18 (1). Nueva York, NY: ACM . doi : 10.1145/948093.948095 . ISSN 0362-1340 . S2CID 6975032. Consultado el 17 de febrero de 2011 .
- 1 2 Cox, Naroff y Hsu (2020) , págs. 10–11.
- ↑ "Common Lisp y Readline" . GitHub . Archivado del original el 6 de septiembre de 2014. Recuperado el 15 de septiembre de 2014. El
problema surgió cuando NeXT propuso distribuir un GCC modificado en dos partes y permitir que el usuario las enlazara. Jobs me preguntó si esto era legal. En ese momento me pareció que sí, siguiendo un razonamiento similar al que estás usando; pero como el resultado era muy indeseable para el software libre, dije que tendría que consultar con el abogado. Lo que dijo el abogado me sorprendió; dijo que los jueces considerarían tales esquemas como "subterfugios" y serían muy severos con ellos. Dijo que un juez preguntaría si es "realmente" un solo programa, en lugar de cómo está etiquetado. Así que volví a hablar con Jobs y le dije que creíamos que su plan no estaba permitido por la GPL. El resultado directo de esto es que ahora tenemos un front-end Objective-C. Querían distribuir el analizador sintáctico de Objective C como un paquete propietario independiente para vincularlo con el backend de GCC, pero como no estuve de acuerdo en que esto estuviera permitido, lo hicieron gratuito.
- ↑ Cox, Naroff y Hsu (2020) , págs. 27–28.
- ↑ "GNUstep: Introducción" . Desarrolladores de GNUstep/Proyecto GNU. Archivado del original el 6 de agosto de 2012. Consultado el 29 de julio de 2012 .
- ↑ Botto, F.; Frith-Macdonald, R.; Pero, N.; Robert, A. (2004). "Historia". Manual de programación base de Objective-C GNUstep (PDF) . pág. 6.
- ↑ "Kresten Krab Thorup | LinkedIn" . www.linkedin.com . Archivado del original el 15 de julio de 2014. Consultado el 23 de junio de 2016 .
- 1 2 3 4 Cox, Naroff y Hsu (2020) , pág. 29.
- ↑ "Escribir código Objective-C" . apple.com. 23 de abril de 2013. Archivado del original el 24 de diciembre de 2013. Consultado el 22 de diciembre de 2013 .
- ↑ "Examinando Objective-C" . Dr. Dobb's . Archivado del original el 4 de septiembre de 2014. Recuperado el 4 de septiembre de 2014. Objective
-C es un superconjunto estricto orientado a objetos de C.
- ↑ Lee (2013) , pág. 3, 381.
- ↑ "Etiquetas para encabezados de Objective-C" . Archivado del original el 1 de abril de 2017. Recuperado el 11 de febrero de 2018. Objective
-C es un superconjunto de C.
- ↑ Tiempo de ejecución (2009) , Resolución dinámica de métodos.
- ↑ Apple, Inc. (19 de octubre de 2009). "Cómo evitar errores de mensajería" . El lenguaje de programación Objective-C . Archivado del original el 8 de septiembre de 2010.
- ↑ Tiempo de ejecución (2009) , Mensajería.
- ↑ "objc_msgSend - Objective-C Runtime" . Documentación para desarrolladores de Apple . Consultado el 10 de febrero de 2020 .
- ↑ "Mensajería con el entorno de ejecución GNU Objective-C" . Uso de la colección de compiladores GNU (GCC) . Consultado el 10 de febrero de 2020 .
- ↑ "Categoría" . Desarrollador de Apple (Competencias básicas de Cocoa) .
- ↑ Dalrymple, Mark; Knaster, Scott (27 de junio de 2012). Aprende Objective-C en Mac . Apress. pág. 9. ISBN 9781430241881La extensión .m
originalmente significaba "mensajes" cuando se introdujo Objective-C por primera vez, en referencia a una característica central de Objective-C.
- ↑ Tiempo de ejecución (2009) , Reenvío de mensajes.
- 1 2 3 Cox, Naroff y Hsu (2020) , págs. 23–24.
- ↑ Wagner, Bill (20 de noviembre de 2025). "Métodos de extensión (Guía de programación de C#)" . Microsoft Learn . Microsoft.
- ↑ Whitney, Tyler (29 de agosto de 2019). "Directiva #import (C++)" . Microsoft Learn . Microsoft .
- ↑ "Objective-C 2.0: más pistas" . Lists.apple.com. 10 de agosto de 2006. Archivado del original el 18 de junio de 2009. Consultado el 30 de mayo de 2010 .
- ↑ "Re: Objective-C 2.0" . Lists.apple.com. Archivado del original el 24 de noviembre de 2010. Consultado el 30 de mayo de 2010 .
- 1 2 "Serie de lanzamientos de GCC 4.6: cambios, nuevas características y correcciones : Proyecto GNU : Fundación del Software Libre" . Gcc.gnu.org . Archivado del original el 5 de enero de 2018. Recuperado el 24 de diciembre de 2017 .
- 1 2 3 4 5 "Preguntas frecuentes sobre ObjC2" . GNUstep . Consultado el 6 de enero de 2020 .
- ↑ "Navegador de código fuente: objc4, 756.2" . Apple Open Source . Archivado del original el 6 de agosto de 2020. Consultado el 6 de enero de 2020 .
- ↑ Guía de programación de recolección de basura: API de recolección de basura. Archivado el 9 de junio de 2012 en Wayback Machine (sitio web para desarrolladores de Apple; busque "__strong").
- ↑ "Guía de programación de recolección de basura: Introducción a la recolección de basura" . Apple Inc. 3 de octubre de 2011. Archivado del original el 9 de junio de 2012. Consultado el 23 de diciembre de 2011 .
- ↑ "Serie de tecnología Leopard para desarrolladores: Descripción general de Objective-C 2.0" . Apple Inc. 6 de noviembre de 2007. Archivado del original el 24 de julio de 2010. Consultado el 30 de mayo de 2010 .
- ↑ "Notas de la versión de transición a ARC" . Apple Inc. 17 de julio de 2012. Archivado del original el 9 de junio de 2012. Consultado el 26 de agosto de 2012 .
- ↑ Mike Ash. "Preguntas y respuestas del viernes 27 de septiembre de 2013: ARM64 y usted" . mikeash.com. Archivado del original el 26 de abril de 2014. Consultado el 27 de abril de 2014 .
- ↑ "Hamster Emporium: [ objc explain ] : Non-pointer isa" . Sealiesoftware.com. 24 de septiembre de 2013. Archivado del original el 3 de junio de 2014. Recuperado el 27 de abril de 2014 .
- ↑ Apple, Inc. (2009). "Enumeración rápida" . apple.com. Archivado del original el 17 de diciembre de 2009. Recuperado el 31 de diciembre de 2009 .
- ↑ Free Software Foundation, Inc. (2011). "GCC 4.6 Release Series – Changes, New Features, and Fixes" . Gcc.gnu.org . Archivado del original el 2 de diciembre de 2013. Consultado el 27 de noviembre de 2013 .
- ↑ "Temas de programación de bloques – Biblioteca para desarrolladores de Mac" . Apple Inc. 8 de marzo de 2011. Archivado del original el 9 de junio de 2012. Consultado el 28 de noviembre de 2012 .
- 1 2 3 "Conteo automático de referencias (ARC) de Objective-C — Documentación de Clang 11" . Documentación de Clang . Consultado el 20 de febrero de 2020.
Por ahora, es sensato versionar este documento según las versiones de su única implementación (y su proyecto anfitrión), clang. "LLVM XY" se refiere a una versión de código abierto de clang del proyecto LLVM. "Apple XY" se refiere a una versión del compilador LLVM de Apple proporcionada por Apple.
- ↑ "Transición a ARC" . Apple Inc. Archivado del original el 7 de septiembre de 2011. Consultado el 8 de octubre de 2012 .
- ↑ "Notas de la versión LLVM 3.0" . releases.llvm.org .
- 1 2 "Programación con Objective-C: Valores y colecciones" . Apple Inc. Archivado del original el 7 de septiembre de 2011. Recuperado el 8 de octubre de 2012 .
- ↑ "Notas de la versión de Clang 3.1" . releases.llvm.org .
- ↑ "@yamaya's GitHub Gist documentando el 'registro de versión de clang de Xcode'"" . Archivado del original el 17 de febrero de 2025 . Recuperado el 17 de febrero de 2025 .
- ↑ "Notas de la versión de Xcode 13 > Compilador Apple Clang > Nuevas características" . Archivado del original el 17 de febrero de 2025. Consultado el 17 de febrero de 2025 .
- ↑ "Literales de Objective-C — Documentación de Clang 3.5" . Clang.llvm.org. Archivado del original el 6 de junio de 2014. Consultado el 16 de abril de 2014 .
- 1 2 Cox, Naroff y Hsu (2020) , págs. 24–25.
- 1 2 "Uso de C++ con Objective-C" . Biblioteca de referencia de Mac OS X. Archivado del original el 5 de septiembre de 2010. Recuperado el 12 de febrero de 2025 .
- ↑ "Extensiones del lenguaje Clang — Documentación de Clang 3.5" . Clang.llvm.org. Archivado del original el 24 de febrero de 2014. Consultado el 16 de abril de 2014 .
- ↑ Guía del desarrollador de Rhapsody , AP Professional, 1997, págs. 76–84
- ↑ "gcc/libobjc" . GitHub . gcc-mirror. 6 de enero de 2020. Consultado el 6 de enero de 2020. El entorno de ejecución se ha reescrito completamente en gcc 2.4 .
El entorno de ejecución anterior tenía varios errores graves y era bastante incompleto.
- ↑ "API de tiempo de ejecución de GNU Objective-C" . Usando GCC . Consultado el 6 de enero de 2020 .
- ↑ "WinObjC en GitHub" . GitHub . Archivado del original el 2 de diciembre de 2017. Consultado el 13 de febrero de 2018 .
- ↑ "Instalador de GNUStep" . Archivado del original el 17 de febrero de 2018. Consultado el 14 de febrero de 2018 .
- ↑ Mulle, N (2015). "mulle-objc: un nuevo Objective-C" .
- ↑ "Introducción" . Proyecto mulle-objc . Consultado el 26 de enero de 2026 .
- ↑ Mulle, N. "Porting: Differences to Objective-C 2.0". De Re mulle-objc .
- ↑ "Compilador de objetos portátil" . Usuarios.pandora.be. 1 de enero de 1970. Archivado del original el 2 de agosto de 2008. Consultado el 30 de mayo de 2010 .
- 1 2 Chisnall (2011) , pág. 83.
- ↑ "Notas de la versión de transición a ARC" . Biblioteca para desarrolladores de iOS . Developer.apple.com. Archivado del original el 7 de septiembre de 2011. Consultado el 16 de abril de 2014 .
- ↑ Chisnall (2011) , pág. 91.
Bibliografía
- Guía de programación del entorno de ejecución de Objective-C . Apple Inc. 19 de octubre de 2009.
- Chisnall, David (octubre de 2011). Libro de frases de Objective-C (2ª ed.). Addison-Wesley . ISBN 978-0-321-81375-6.
- Cox, Brad J.; Naroff, S.; Hsu, H. (12 de junio de 2020). "Los orígenes de Objective-C en PPI/Stepstone y su evolución en NeXT" . Actas de la ACM sobre lenguajes de programación . 4 (HOPL). Association for Computing Machinery : 1–74 . doi : 10.1145/3386332 . eISSN 2475-1421 .
- Lee, Keith (3 de septiembre de 2013). Pro Objective-C . Berkeley, CA: Apress . doi : 10.1007/978-1-4302-5051-7 . ISBN 978-1-4302-5050-0.
Lecturas adicionales
- Cox, Brad J. (1991). Programación orientada a objetos: un enfoque evolutivo . Addison Wesley. ISBN 0-201-54834-8.
Enlaces externos
- Programación con Objective-C , de Apple (13 de diciembre de 2012)
- El lenguaje de programación Objective-C , de Apple (17 de septiembre de 2014)
- Manual de programación básica de Objective-C GNUstep
- Objective-C por Brad Cox
- Preguntas frecuentes sobre Objective-C
- Ejemplo en Objective-C ( Archivado el 23 de abril de 2024 en Wayback Machine )
- Objetivo-C
- Familia de lenguajes de programación C
- Lenguajes de programación basados en clases
- Lenguajes de programación compilados
- Lenguajes de programación de tipado dinámico
- GNUstep
- Próximo
- Lenguajes de programación orientados a objetos
- Lenguajes de programación creados en 1986