Objective-C es una de propósito general , orientado a objetos lenguaje de programación que se suma Smalltalk al estilo de mensajería a la C lenguaje de programación. Es uno de los dos lenguajes de programación principales admitidos por Apple para macOS , iOS y sus respectivas interfaces de programación de aplicaciones (API), Cocoa y Cocoa Touch . Fue el idioma principal singular hasta la introducción de Swift en 2014. [3]
Familia | C |
---|---|
Diseñada por | Tom Love y Brad Cox |
Apareció por primera vez | 1984 |
Lanzamiento estable | 2.0 [1] |
Disciplina de mecanografía | estático , dinámico , débil |
SO | Multiplataforma |
Extensiones de nombre de archivo | .h, .m, .mm, .M |
Sitio web | developer.apple.com |
Implementaciones importantes | |
Clang , GCC | |
Influenciado por | |
C , Smalltalk | |
Influenciado | |
Groovy , Java , Nu , Objective-J , TOM , Swift [2] | |
|
El lenguaje se desarrolló originalmente a principios de la década de 1980. Más tarde fue seleccionado como el idioma principal utilizado por NeXT para su sistema operativo NeXTSTEP , del cual se derivan macOS e iOS. [4] Los programas portátiles Objective-C que no usan bibliotecas de Apple, o aquellos que usan partes que pueden ser portadas o reimplementadas para otros sistemas, también pueden compilarse para cualquier sistema soportado por GNU Compiler Collection (GCC) o Clang .
Los archivos de programa de 'implementación' del código fuente de Objective-C generalmente tienen extensiones de nombre de archivo .m , mientras que los archivos de 'encabezado / interfaz' de Objective-C tienen extensiones .h , al igual que los archivos de encabezado C. Los archivos Objective-C ++ se indican con una extensión de archivo .mm .
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) . [5]
Antes de la creación de su empresa, ambos conocieron Smalltalk mientras estaban en el Centro de Tecnología de Programación de ITT Corporation en 1981. El trabajo más temprano en Objective-C se remonta a esa época. [6] Cox estaba intrigado por los problemas de la verdadera reutilización en el diseño y la programación de software . Se dio cuenta de que un lenguaje como Smalltalk sería invaluable en la creación de entornos de desarrollo para 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. [7]
Cox comenzó a escribir un preprocesador para C para agregar algunas de las habilidades de Smalltalk. Pronto tuvo una implementación funcional de una extensión orientada a objetos para el lenguaje C , que llamó "OOPC" para precompilador orientado a objetos. [8] 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. Para demostrar que se podía lograr un progreso real, Cox demostró que la fabricación de componentes de software intercambiables realmente solo necesitaba unos pocos cambios prácticos en las herramientas existentes. Específicamente, necesitaban admitir objetos de manera flexible, contar con un conjunto de bibliotecas utilizables y permitir que el código (y los recursos necesarios para el código) se agruparan en un formato multiplataforma.
Love y Cox finalmente formaron PPI para comercializar su producto, que combinó un compilador Objective-C con bibliotecas de clases. En 1986, Cox publicó la descripción principal de Objective-C en su forma original en el libro Programación orientada a objetos, un enfoque evolutivo . Aunque tuvo cuidado de señalar que hay más en el problema de la reutilización que lo que proporciona Objective-C, el lenguaje a menudo se encontró comparado 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, el propietario de la marca registrada Objective-C) y extendió el compilador GCC para admitir Objective-C. NeXT desarrolló las bibliotecas AppKit y Foundation Kit en las que se basaron la interfaz de usuario y el Interface Builder de NeXTSTEP . Si bien las estaciones de trabajo NeXT no lograron tener un gran impacto en el mercado, las herramientas fueron ampliamente elogiadas en la industria. Esto llevó a NeXT a abandonar la producción de hardware y centrarse en herramientas de software, vendiendo NeXTSTEP (y OpenStep) como una plataforma para la programación personalizada.
Para eludir los términos de la GPL , NeXT originalmente tenía la intención de enviar la interfaz de Objective-C por separado, permitiendo al usuario vincularla con GCC para producir el ejecutable del compilador. Aunque inicialmente aceptado por Richard M. Stallman , este plan fue rechazado después de que Stallman consultó con los abogados de GNU y NeXT acordó hacer que Objective-C formara parte de GCC. [9]
El trabajo para extender GCC fue dirigido por Steve Naroff, quien se unió a NeXT desde StepStone. Los cambios del compilador se pusieron a disposición según los términos de la licencia GPL , pero las bibliotecas en tiempo de ejecución no lo estaban, lo que hizo que la contribución de código abierto fuera inutilizable para el público en general. Esto llevó a otras partes a desarrollar tales bibliotecas en tiempo de ejecución bajo licencia de código abierto. Más tarde, Steve Naroff también fue el principal colaborador para trabajar en Apple para construir la interfaz Objective-C para Clang .
El proyecto GNU comenzó a trabajar en su implementación de software libre de Cocoa , llamado GNUstep , basado en el estándar OpenStep . [10] Dennis Glatting escribió el primer tiempo de ejecución GNU Objective-C en 1992. El tiempo de ejecución GNU Objective-C, que ha estado en uso desde 1993, es el desarrollado por Kresten Krab Thorup cuando era un estudiante universitario en Dinamarca . [ cita requerida ] Thorup también trabajó en NeXT de 1993 a 1996. [11]
Desarrollo de Apple y Swift
Después de la adquisición de NeXT en 1996, Apple Computer utiliza OpenStep en su entonces nuevo sistema operativo, Mac OS X . Esto incluyó Objective-C, la herramienta de desarrollo basada en Objective-C de NeXT, Project Builder , y su herramienta de diseño de interfaz, Interface Builder . Ambos se fusionaron más tarde en una sola aplicación, Xcode . La mayor parte de la API Cocoa actual de Apple se basa en objetos de interfaz OpenStep y es el entorno Objective-C más importante que se utiliza para el desarrollo activo.
En WWDC 2014, Apple presentó un nuevo lenguaje, Swift , que se caracterizó como "Objective-C sin la C".
Sintaxis
Objective-C es una capa delgada encima de 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 en lenguaje C dentro de una clase Objective-C. [12] [13] [14] [15] [16] [17]
Objective-C deriva su sintaxis de objeto de Smalltalk . Toda la sintaxis de las operaciones no orientadas a objetos (incluidas las variables primitivas, el preprocesamiento, las expresiones, las declaraciones de funciones y las llamadas a funciones) son idénticas a las de C, mientras que la sintaxis de las funciones orientadas a objetos es una implementación de Smalltalk- mensajes de estilo.
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 uno no llama a un método ; uno envía un mensaje . Esto es diferente al modelo de programación estilo Simula utilizado por C ++ . La diferencia entre estos dos conceptos está en cómo se ejecuta el código al que hace referencia el método o el nombre del mensaje. En un lenguaje de estilo Simula, el nombre del método en la mayoría de los casos está vinculado a una sección de código en la clase de destino por el compilador. En Smalltalk y Objective-C, el objetivo de un mensaje se resuelve en tiempo de ejecución, y el propio objeto receptor interpreta el mensaje. Un método se identifica mediante un selector o SEL : un identificador único para cada nombre de mensaje, a menudo solo un Cadena terminada en NUL que representa su nombre y resuelta en un puntero de método Cimplementándola: IMP . [18] Una consecuencia de esto es que el sistema de paso de mensajes no tiene verificación de tipo. No se garantizaque el objeto al que se dirige el mensaje, el receptor , responda a un mensaje y, si no lo hace, genera una excepción. [19]
Enviando el mensaje método al objeto apuntado por el puntero obj requerirí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 ];
El compilador traduce la llamada al "método" al objc_msgSend (id self, SEL op, ...) familia de funciones en tiempo de ejecución. Diferentes implementaciones manejan adiciones modernas como super . [20] En las familias GNU, esta función se denomina objc_msg_sendv , pero ha quedado obsoleto en favor de un sistema de búsqueda moderno bajo objc_msg_lookup . [21]
Ambos estilos de programación tienen sus fortalezas y debilidades. La programación orientada a objetos en el estilo Simula ( C ++ ) permite una herencia múltiple y una ejecución más rápida mediante el uso de enlace en tiempo de compilación siempre que sea posible, pero no admite el enlace dinámico de forma predeterminada. También obliga a todos los métodos a tener una implementación correspondiente a menos que sean abstractos . La programación de estilo Smalltalk como se usa en Objective-C permite que los mensajes no se implementen, con el método resuelto para su implementación en tiempo de ejecución. Por ejemplo, se puede enviar un mensaje a una colección de objetos, a los que se esperará que solo algunos respondan, sin temor a producir errores en tiempo de ejecución. El paso de mensajes tampoco requiere que se defina un objeto en tiempo de compilación. Aún se requiere una implementación para que se llame al método en el objeto derivado. (Consulte la sección de escritura dinámica a continuación para obtener más ventajas de la vinculación dinámica (tardía)).
Interfaces e implementaciones
Objective-C requiere que la interfaz y la implementación de una clase estén en bloques de código declarados por separado. Por convención, los desarrolladores colocan la interfaz en un archivo de encabezado y la implementación en un archivo de código. Los archivos de encabezado, normalmente con el sufijo .h, son similares a los archivos de encabezado de C, mientras que los archivos de implementación (método), normalmente con el sufijo .m, pueden ser muy similares a los archivos de código C.
Interfaz
Esto es análogo a las declaraciones de clases que se usan en otros lenguajes orientados a objetos, como C ++ o Python.
La interfaz de una clase generalmente se define en un archivo de encabezado. Una convención común es nombrar el archivo de encabezado después del nombre de la clase, p. Ej. Ball.h contendría la interfaz de la clase Ball .
Una declaración de interfaz tiene la forma:
@interface classname : superclassname { // variables de instancia } + classMethod1 ; + ( Return_type ) classMethod2 ; + ( Return_type ) classMethod3: ( param1_type ) param1_varName ;- ( return_type ) instanceMethod1With1Parameter: ( param1_type ) param1_varName ; - ( return_type ) instanceMethod2With2Parameters: ( param1_type ) param1_varName param2_callName: ( param2_type ) param2_varName ; @final
En lo anterior, los signos más denotan métodos de clase , o métodos que se pueden llamar en la propia clase (no en una instancia), y los signos menos denotan 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 ++ :
class classname : public superclassname { protected : // variables de instanciapublic : // Funciones de clase (estáticas) static void * classMethod1 (); estática return_type classMethod2 (); estática 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 = predeterminado ); };
Tenga en cuenta que instanceMethod2With2Parameters: param2_callName: demuestra el entrelazado de segmentos selectores con expresiones de argumentos, para los cuales no existe un equivalente directo en C / C ++.
Los tipos de retorno pueden ser cualquier tipo C estándar , un puntero a un objeto Objective-C genérico, 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 Objective-C genérico id .
Los argumentos del método comienzan con un nombre que etiqueta el argumento que forma parte del nombre del método, seguido de dos puntos seguidos del tipo de argumento esperado entre paréntesis y el nombre del argumento. La etiqueta se puede omitir.
- ( void ) setRangeStart: ( int ) inicio fin: ( int ) fin ; - ( void ) importDocumentWithName: ( NSString * ) nombre withSpecifiedPreferences: ( Preferences * ) prefs beforePage: ( int ) insertPage ;
Un derivado de la definición de interfaz es la categoría , que permite agregar métodos a las clases existentes. [22]
Implementación
La interfaz solo declara la interfaz de clase y no los métodos en sí: el código real está escrito en el archivo de implementación. Los archivos de implementación (método) normalmente tienen la extensión de archivo .m
, que originalmente significaba "mensajes". [23]
@implementation nombre de clase + ( return_type ) classmethod { // implementación } - ( return_type ) instanceMethod { // implementación } @end
Los 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 ]; }
int function ( int i ) { return raíz_cuadrada ( i ); }
La sintaxis permite pseudonombrar argumentos .
- ( void ) changeColorToRed: ( flotante ) rojo verde: ( flotante ) verde azul: ( flotante ) azul { // ... Implementación ... }// Llamado así: [ myColor changeColorToRed : 5.0 verde : 2.0 azul : 6.0 ];
Las representaciones internas de un método varían entre diferentes implementaciones de Objective-C. Si myColor es de la clase Color , método de instancia -changeColorToRed: verde: azul: puede estar etiquetado internamente _i_Color_changeColorToRed_green_blue . La i es hacer referencia a un método de instancia, con la clase y luego los nombres del método agregados y los dos puntos cambiados a guiones bajos. Como el orden de los parámetros es parte del nombre del método, no se puede cambiar para adaptarse al estilo de codificación o expresión como con los parámetros con nombre verdadero.
Sin embargo, los nombres internos de la función 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 se sabe necesariamente en el momento del enlace qué método se llamará porque no es necesario conocer la clase del receptor (el objeto al que se envía el mensaje) hasta el tiempo de ejecución.
Instanciación
Una vez que se escribe una clase Objective-C, se puede crear una instancia. Esto se hace 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 línea de código para que nunca haya un objeto asignado que no se haya inicializado (y porque no es prudente mantener el resultado intermedio, ya que -init
puede devolver un objeto diferente al que se llama).
Creación de instancias con el inicializador sin parámetros predeterminado:
MyObject * foo = [[ MyObject alloc ] init ];
Creación de instancias con un inicializador personalizado:
MyObject * foo = [[ MyObject alloc ] initWithString : myString ];
En el caso de que no se realice una inicialización personalizada, el método "nuevo" a menudo se puede utilizar en lugar de los mensajes alloc-init:
MyObject * foo = [ MyObject nuevo ];
Además, algunas clases implementan inicializadores de métodos de clase. Me gusta +new
, se combinan +alloc
y -init
, pero a diferencia +new
, devuelven una instancia liberada automáticamente. Algunos inicializadores de métodos de clase toman parámetros:
MyObject * foo = [ MyObject object ]; MyObject * bar = [ MyObject objectWithString : @ "Wikipedia :)" ];
El alloc asigna memoria mensaje suficiente para mantener todas las variables de instancia para 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 de inicio realiza la configuración de la instancia al momento de su creación. El método init a menudo se escribe de la siguiente manera:
- ( id ) init { self = [ super init ]; if ( self ) { // realiza la inicialización del objeto aquí } return self ; }
En el ejemplo anterior, observe el id
tipo de retorno. Este tipo significa "puntero a cualquier objeto" en Objective-C (consulte la sección Escritura dinámica ).
El patrón de inicialización 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:
- self = [super init]
- Envía a la instancia de la superclase un mensaje de inicialización y asigna el resultado a self (puntero al objeto actual).
- si (yo)
- Comprueba si el puntero del objeto devuelto es válido antes de realizar cualquier inicialización.
- Regresar
- Devuelve el valor de sí mismo a la persona que llama.
Un puntero de objeto no válido tiene el valor nil ; Las sentencias condicionales como "if" tratan 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 mensaje de "liberación" a sí mismo, y devolver nil para indicar que la inicialización falló. Cualquier verificación de tales errores solo debe realizarse después de haber llamado a la inicialización de la superclase para asegurarse de 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; otros deberían llamar al inicializador designado en lugar del inicializador de superclase.
Protocolos
En otros lenguajes de programación, estos se denominan "interfaces".
Objective-C se amplió en NeXT para introducir el concepto de herencia múltiple de especificación, pero no implementación, mediante la introducción de protocolos . Este es un patrón que se puede lograr como una clase base heredada múltiple abstracta en C ++ o como una "interfaz" (como en Java y C # ). Objective-C hace uso de protocolos ad hoc llamados protocolos informales y protocolos aplicados por el compilador llamados 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 tiene presencia en el idioma. Los protocolos informales se implementan como una categoría (ver más abajo) en NSObject y a menudo incluyen métodos opcionales que, si se implementan, pueden cambiar el comportamiento de una clase. Por ejemplo, una clase de campo de texto puede tener un delegado que implemente un protocolo informal con un método opcional para completar automáticamente el texto escrito por el usuario. El campo de texto descubre si el delegado implementa ese método (a través de la reflexión ) y, si es así, llama al método del delegado para admitir la función de autocompletar.
Un protocolo formal es similar a una interfaz en Java, C # y Ada 2005 . Es una lista de métodos que cualquier clase puede declarar implementar. Las versiones de Objective-C anteriores a la 2.0 requerían que una clase implemente todos los métodos en un protocolo que declara adoptar; el compilador emitirá un error si la clase no implementa todos los métodos de sus protocolos declarados. Objective-C 2.0 agregó soporte para marcar ciertos métodos en un protocolo como opcionales, y el compilador no impondrá la implementación de métodos opcionales.
Se debe declarar una clase para implementar ese protocolo para que se diga que se ajusta a él. Esto es detectable en tiempo de ejecución. Los protocolos formales no pueden proporcionar ninguna implementación; simplemente aseguran a las personas que llaman que las clases que se ajustan al protocolo proporcionarán implementaciones. En la biblioteca NeXT / Apple, los protocolos se utilizan con frecuencia por el sistema de objetos distribuidos para representar las capacidades de un objeto que se ejecuta en un sistema remoto.
La sintaxis
@protocol NSLocking - ( anulado ) bloqueo ; - ( anulado ) desbloqueo ; @final
denota que existe la idea abstracta de bloqueo. Al indicar en la definición de clase que se implementa el protocolo,
@interface NSLock : NSObject < NSLocking > // ... @end
Las instancias de NSLock afirman que proporcionarán una implementación para los dos métodos de instancia.
Escritura dinámica
Objective-C, como Smalltalk, puede utilizar la escritura dinámica : se puede enviar un mensaje a un objeto que no está especificado en su interfaz. Esto puede permitir una mayor flexibilidad, ya que permite que un objeto "capture" un mensaje y envíe el mensaje a un objeto diferente que pueda responder al mensaje de manera apropiada, o igualmente enviar el mensaje a otro objeto. Este comportamiento se conoce como reenvío o delegación de mensajes (ver más abajo). Alternativamente, se puede utilizar un controlador 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 de tiempo de ejecución. [24] Si los mensajes se envían a cero (el puntero de objeto nulo), se ignorarán silenciosamente o generarán una excepción genérica, según las opciones del compilador.
Opcionalmente, también se puede agregar información de escritura estática a las variables. Luego, esta información se verifica en el momento de la compilación. En las siguientes cuatro declaraciones, se proporciona información de tipo cada vez más específica. Las declaraciones 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.
- ( vacío ) setMyValue: ( id ) foo ;
En la declaración anterior, foo puede ser de cualquier clase.
- ( vacío ) setMyValue: ( id < NSCopying > ) foo ;
En la declaración anterior, foo puede ser una instancia de cualquier clase que se ajuste al NSCopying
protocolo.
- ( vacío ) setMyValue: ( NSNumber * ) foo ;
En la declaración anterior, foo debe ser una instancia de la clase NSNumber .
- ( vacío ) setMyValue: ( NSNumber < NSCopying > * ) foo ;
En la declaración anterior, foo debe ser una instancia de la clase NSNumber y debe ajustarse al NSCopying
protocolo.
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 que Identificación del ( objc_obj * ) apunta, que solo tiene un puntero isa que describe su clase. Otros tipos de C, como valores y estructuras, no se modifican 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 unidas.
Reenvío
Objective-C permite el envío de un mensaje a un objeto que puede no responder. En lugar de responder o simplemente dejar caer el mensaje, un objeto puede reenviar el mensaje a un objeto que puede responder. El reenvío se puede utilizar para simplificar la implementación de ciertos patrones de diseño , como el patrón de observador o el patrón de proxy .
El tiempo de ejecución de Objective-C especifica un par de métodos en Objeto
- métodos de reenvío:
- ( retval_t ) adelante: ( SEL ) sel args: ( arglist_t ) args ; // con GCC - ( id ) adelante: ( 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 anular el método de reenvío con un nuevo método para definir el comportamiento de reenvío. El método de acción performv :: no necesita ser anulado, ya que este método simplemente realiza una acción basada en el selector y los argumentos. Observe el SEL
tipo, que es el tipo de mensajes en Objective-C.
Nota: en OpenStep, Cocoa y GNUstep, los frameworks comúnmente usados de Objective-C, uno no usa el Clase de objeto . La - (void) forwardInvocation: (NSInvocation *) un método de invocación del La clase NSObject se utiliza para realizar reenvíos.
Ejemplo
A continuación, se muestra un ejemplo de un programa que demuestra los conceptos básicos del reenvío.
- Forwarder.h
#import @interface Forwarder : Object { id del destinatario ; // El objeto al que queremos reenviar el mensaje. }// Métodos de acceso. - ( id ) destinatario ; - ( id ) setRecipient: ( id ) _recipient ; @final
- Reenviador.m
#importar "Forwarder.h"@implementation Forwarder - ( retval_t ) forward: ( SEL ) sel args: ( arglist_t ) args { / * * Verifica 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 hacerlo * él mismo. * / Si ([ destinatario respondsToSelector : sel ]) { retorno [ receptores performv : sel args : args ]; } else { return [ error propio : "El destinatario no responde" ]; } } - ( id ) setRecipient: ( id ) _recipient { [ liberación automática del destinatario ]; destinatario = [ _recipiente retener ]; volver a sí mismo ; } - ( id ) destinatario { destinatario de retorno ; } @end
- Destinatario.h
#import // Un objeto Recipient simple. @interface Destinatario : Objeto - ( id ) hola ; @final
- Destinatario.m
#importar "Recipient.h"@Receptor de implementación- ( id ) hola { printf ( "¡El destinatario dice hola! \ n " ); volver a sí mismo ; }@final
- main.m
#importar "Forwarder.h" #importar "Recipient.h"int main ( void ) { Reenviador * reenviador = [ Reenviador nuevo ]; Destinatario * destinatario = [ Destinatario nuevo ]; [ reenviador setRecipient : destinatario ]; // Establecer el destinatario. / * * ¡Observe que el reenviador no responde a un mensaje de saludo! Se reenviará *. Todos los métodos no reconocidos serán reenviados al * destinatario * (si el destinatario les responde, como está escrito en el Reenviador) * / [ reenviador hola ]; [ liberación del destinatario ]; [ liberación del transportista ]; return 0 ; }
Notas
Cuando se compila con gcc , el compilador informa:
$ gcc -x objetivo-c -Wno-import Forwarder.m Recipient.m main.m -lobjcmain.m: En función `main ':main.m: 12: advertencia: 'Reenviador' no responde a 'hola'PS
El compilador informa el punto mencionado anteriormente, que El reenviador no responde a los mensajes de saludo. En esta circunstancia, es seguro ignorar la advertencia ya que se implementó el reenvío. La ejecución del programa produce esta salida:
$ ./a.out¡El destinatario dice hola!
Categorias
Durante el diseño de Objective-C, una de las principales preocupaciones fue la mantenibilidad de grandes bases de código. La experiencia del mundo de la programación estructurada había demostrado que una de las principales formas de mejorar el código era dividirlo en partes más pequeñas. Objective-C tomó prestado y amplió el concepto de categorías de las implementaciones de Smalltalk para ayudar con este proceso. [25]
Además, los métodos dentro de una categoría se agregan a una clase en tiempo de ejecución . Por lo tanto, las categorías permiten al programador agregar métodos a una clase existente, una clase abierta , sin la necesidad de volver a compilar esa clase o incluso tener acceso a su código fuente. Por ejemplo, si un sistema no contiene un corrector ortográfico en su implementación de String, podría agregarse sin modificar el código fuente de String.
Los métodos dentro de las categorías se vuelven indistinguibles de los métodos de una clase cuando se ejecuta el programa. 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 de método 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 que también pueden reemplazar los métodos existentes. Esta función se puede utilizar 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 de métodos, no está definido qué método de categoría se adopta.
Otros idiomas han intentado agregar esta función de diversas formas. TOM llevó el sistema Objective-C un paso más allá y permitió la adición de variables también. En su lugar, otros lenguajes han utilizado soluciones basadas en prototipos , siendo el más notable Self .
Los lenguajes C # y Visual Basic.NET implementan una funcionalidad superficialmente similar en forma de métodos de extensión , pero estos carecen de acceso a las variables privadas de la clase. [26] Ruby y varios otros lenguajes de programación dinámica se refieren a la técnica como " parche de mono ".
Logtalk implementa un concepto de categorías (como entidades de primera clase) que subsume la funcionalidad de categorías de Objective-C (las categorías de Logtalk también se pueden usar como unidades de composición detalladas al definir, por ejemplo, nuevas clases o prototipos; en particular, una categoría de Logtalk puede ser prácticamente importado por cualquier número de clases y prototipos).
Ejemplo de uso de categorías
Este ejemplo construye un Clase entera , definiendo primero una clase básica con solo métodos de acceso implementados y agregando dos categorías, Aritmética y Display , que amplía 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. La implementación de estos accesos es un uso típico de las categorías. Otra es usar categorías para agregar métodos a la clase base. Sin embargo, no se considera una buena práctica utilizar categorías para anular subclases, también conocido como parche de mono . Los protocolos informales se implementan como una categoría en la base Clase NSObject . Por convención, los archivos que contienen categorías que amplían las clases base tomarán el nombre BaseClass + ExtensionClass.h .
- Entero.h
#import @interface Integer : Object { int integer ; }- ( int ) entero ; - ( id ) entero: ( int ) _integer ; @final
- Entero.m
#importar "Integer.h"@implementation Integer - ( int ) integer { return integer ; }- ( id ) entero: ( int ) _integer { integer = _integer ; volver a sí mismo ; } @end
- Entero + Aritmética.h
#importar "Integer.h"@interface Integer (Aritmética) - ( id ) agregar: ( Integer * ) sumando ; - ( id ) sub: ( Entero * ) sustraendo ; @final
- Entero + Aritmética.m
# importar "Entero + Aritmética.h"@implementation Integer (aritmético) - ( id ) suma: ( Integer * ) sumando { return [ self integer : [ self integer ] + [ sumando integer ]]; }- ( id ) sub: ( Entero * ) sustraendo { return [ auto entero : [ auto entero ] - [ sustraendo entero ]]; } @end
- Entero + Display.h
#importar "Integer.h"@interface Integer (Display) - ( id ) showstars ; - ( id ) showint ; @final
- Entero + Display.m
# importar "Integer + Display.h"@implementation Integer (Display) - ( id ) showstars { int i , x = [ self integer ]; para ( i = 0 ; i < x ; i ++ ) { printf ( "*" ); } printf ( " \ n " ); volver a sí mismo ; }- ( id ) showint { printf ( "% d \ n " , [ self integer ]); volver a sí mismo ; } @end
- main.m
#importar "Integer.h" #import "Integer + Arithmetic.h" #import "Integer + Display.h"int main ( void ) { Integer * num1 = [ Integer new ], * num2 = [ Integer new ]; int x ; printf ( "Ingrese un número entero:" ); scanf ( "% d" , & x ); [ núm1 entero : x ]; [ NUM1 showstars ]; printf ( "Ingrese un número entero:" ); scanf ( "% d" , & x ); [ núm2 entero : x ]; [ Num2 showstars ]; [ num1 agregar : num2 ]; [ num1 showint ]; return 0 ; }
Notas
La compilación se realiza, por ejemplo, mediante:
gcc -x objetivo-c main.m Integer.m Integer + Aritmética.m Integer + Display.m -lobjc
Uno puede experimentar dejando fuera el #importar "Integer + Arithmetic.h" y [num1 add: num2] líneas y omitiendo Integer + Arithmetic.m en compilación. El programa seguirá funcionando. Esto significa que es posible mezclar y combinar categorías agregadas si es necesario; si una categoría no necesita tener alguna habilidad, simplemente no se puede compilar.
Posando
Objective-C permite que una clase reemplace completamente a otra clase dentro de un programa. Se dice que la clase que reemplaza "se hace pasar por" la clase objetivo.
La presentación de clases se declaró obsoleta con Mac OS X v10.5 y no está disponible en el tiempo de ejecución de 64 bits. Se puede lograr una funcionalidad similar mediante el uso de métodos agrupados en categorías, que intercambia la implementación de un método con otro que tiene la misma firma.
Para las versiones que aún admiten la presentación, todos los mensajes enviados a la clase de destino son recibidos por la clase de presentación. Existen varias restricciones:
- Una clase solo puede hacerse pasar por una de sus superclases directas o indirectas.
- La clase de presentación no debe definir ninguna variable de instancia nueva que esté ausente de la clase de destino (aunque puede definir o anular métodos).
- Es posible que la clase objetivo no haya recibido ningún mensaje antes de la presentación.
Posar, de manera similar con las categorías, permite el aumento global de las clases existentes. Posar permite dos características ausentes de las categorías:
- Una clase de presentación puede llamar a métodos anulados a través de super, incorporando así la implementación de la clase de destino.
- Una clase de poses puede anular los métodos definidos en 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 #include
directiva de precompilación siempre hace que el contenido de un archivo se inserte en la fuente en ese punto. Objective-C tiene la #import
directiva, equivalente excepto que cada archivo se incluye solo una vez por unidad de compilación, obviando la necesidad de incluir guardias .
Compilación gcc de Linux
// ARCHIVO: hello.m #import int main ( int argc , const char * argv []) { / * mi primer programa en Objective-C * / NSLog ( @ "Hello, World! \ n " ); return 0 ; }
# Compile la línea de comandos para el compilador gcc y 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, a menudo, fáciles para problemas de programación.
- La delegación de métodos a otros objetos y la invocación remota se pueden implementar fácilmente mediante categorías y reenvío de mensajes.
- Swizzling del puntero isa permite que las clases cambien en tiempo de ejecución. Normalmente se usa para depurar donde los objetos liberados se mezclan en objetos zombies cuyo único propósito es informar un error cuando alguien los llama. Swizzling también se usó en Enterprise Objects Framework para crear fallas en la base de datos. [ cita requerida ] Swizzling es utilizado hoy por el Foundation Framework de Apple para implementar la observación de valores clave .
Variantes de idioma
Objetivo-C ++
Objective-C ++ es una variante de lenguaje aceptada por el front-end para GNU Compiler Collection y Clang , que puede compilar archivos fuente que usan una combinación de sintaxis C ++ y Objective-C. Objective-C ++ agrega a C ++ las extensiones que Objective-C agrega a C. Como no se hace nada para unificar la semántica detrás de las diversas características del lenguaje, se aplican ciertas restricciones:
- Una clase C ++ no puede derivar de una clase Objective-C y viceversa.
- Los espacios de nombres de C ++ no se pueden declarar dentro de una declaración de Objective-C.
- Las declaraciones de Objective-C pueden aparecer solo 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 carecen de un constructor predeterminado o que tienen uno o más métodos virtuales, [ cita requerida ] pero los punteros a objetos de C ++ se pueden usar como variables de instancia sin restricción (asígnelos con new en el - método init).
- La semántica "por valor" de C ++ no se puede aplicar a objetos Objective-C, a los que solo se puede acceder mediante 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 Objective-C (p. Ej.,
Classname *
) Se pueden utilizar como parámetros de plantilla de C ++. - El manejo de excepciones de 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 los tiempos de ejecución recientes de "Objective-C 2.0", ya que las excepciones de Objective-C se reemplazan completamente por excepciones de C ++ (tiempo de ejecución de Apple), o en parte cuando la biblioteca Objective-C ++ está vinculada (GNUstep libobjc2). [27]
- Los bloques de Objective-C y las lambdas de C ++ 11 son entidades distintas. Sin embargo, un bloque se genera de forma transparente en macOS cuando se pasa una lambda donde se espera un bloque. [28]
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 para incluir "recolección de basura moderna, mejoras de sintaxis, [29] mejoras de rendimiento en tiempo de ejecución, [30] y 64- soporte de 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 puntos, 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 GNU Objective-C. [31]
El nombramiento de 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". [32] Este nombre de proyecto se mantuvo en la última versión del código fuente en tiempo de ejecución de Objective-C heredado en Mac OS X Leopard (10.5). [33]
Recolección de basura
Objective-C 2.0 proporcionó un recolector de basura generacional conservador opcional . Cuando se ejecuta en modo compatible con versiones anteriores , el tiempo de ejecución convirtió las operaciones de recuento de referencias como "retener" y "liberar" en no-ops . Todos los objetos estaban sujetos a la recolección de elementos no utilizados cuando se habilitó la recolección de elementos no utilizados. Los punteros C regulares podrían calificarse con "__ strong" para activar también las interceptaciones del compilador de barrera de escritura subyacentes y, por lo tanto, participar en la recolección de basura. [34] También se proporcionó un subsistema débil de puesta a cero, de modo que los punteros marcados como "__weak" se ponen a cero cuando se recopila el objeto (o más simplemente, la memoria GC). El recolector de basura no existe en la implementación de iOS de Objective-C 2.0. [35] La recolección de basura en Objective-C se ejecuta en un subproceso en segundo plano de baja prioridad y puede detenerse en los eventos del usuario, con la intención de mantener la experiencia del usuario receptiva. [36]
La recolección de basura quedó obsoleta en Mac OS X v10.8 a favor del Conteo automático de referencias (ARC). [37] Objective-C en iOS 7 que se ejecuta en ARM64 usa 19 bits de una palabra de 64 bits para almacenar el recuento de referencias, como una forma de punteros etiquetados . [38] [39]
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ública; es decir, declarar una variable de instancia como una propiedad proporciona a las clases externas acceso (posiblemente limitado, por ejemplo, sólo lectura) a esa propiedad. Una propiedad se puede declarar como "solo lectura" y se puede proporcionar una semántica de almacenamiento como assign
, copy
o retain
. De forma predeterminada, se consideran las propiedades atomic
, lo que da como resultado 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 * nombre ; @private int age ; }@property ( copia ) NSString * nombre ; @property ( solo lectura ) int edad ;- ( id ) initWithAge: ( int ) edad ; @final
Las propiedades se implementan mediante la @synthesize
palabra clave, que genera métodos getter (y setter, si no de solo lectura) de acuerdo con la declaración de propiedad. Alternativamente, los métodos getter y setter deben implementarse explícitamente, o la @dynamic
palabra clave puede usarse para indicar que los métodos de acceso serán proporcionados por otros medios. Cuando se compila usando clang 3.1 o superior, todas las propiedades que no estén explícitamente declaradas @dynamic
, marcadas readonly
o tengan un getter y setter completo implementado por el usuario serán automáticamente implícitamente @synthesize
'd.
@implementation Person @synthesize nombre ;- ( id ) initWithAge: ( int ) initAge { self = [ super init ]; if ( self ) { // NOTA: asignación directa de variables de instancia, no definidor de propiedades age = initAge ; } return self ; }- ( int ) age { edad de retorno ; } @end
Se puede acceder a las propiedades utilizando la sintaxis tradicional de paso de mensajes, notación de puntos o, en Codificación de valores-clave, por nombre a través de los métodos "valueForKey:" / "setValue: forKey:".
Persona * aPersona = [[ Asignación de personas ] initWithAge : 53 ]; aPerson . nombre = @ "Steve" ; // NOTA: notación de puntos, usa setter sintetizado, // equivalente a [aPerson setName: @ "Steve"]; NSLog ( @ "El acceso a través de mensajes (% @), la notación de puntos (% @), nombre de la propiedad (% @) y directa instancia variable de acceso ( % @) ", [ aperson nombre ], aperson . Nombre , [ aperson valueForKey : @ "nombre" ], unaPersona -> nombre );
Para usar la notación de puntos para invocar accesos de propiedad dentro de un método de instancia, se debe usar la palabra clave "self":
- ( void ) introduceMyselfWithProperties: ( BOOL ) useGetter { NSLog ( @ "Hola, mi nombre es% @." , ( useGetter ? self . name : name )); // NOTA: getter vs. ivar access }
Las propiedades de una clase o protocolo pueden introspectarse dinámicamente .
int i ; int propertyCount = 0 ; objc_property_t * propertyList = class_copyPropertyList ([ una clase de persona ], & 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 las admite el tiempo de ejecución (es decir, cuando se crea código para macOS de 64 bits y todos los iOS). En el tiempo de ejecución moderno, se agrega una capa adicional de direccionamiento indirecto al acceso a la variable de instancia, lo que permite que el enlazador dinámico ajuste el diseño de la instancia en tiempo de ejecución. Esta característica permite dos importantes mejoras al código Objective-C:
- Elimina el frágil problema de la interfaz binaria ; las superclases pueden cambiar de tamaño sin afectar la compatibilidad binaria.
- Permite que las variables de instancia que brindan respaldo a las propiedades se sinteticen en tiempo de ejecución sin que se declaren en la interfaz de la clase.
Enumeración rápida
En lugar de utilizar índices o un objeto NSEnumerator para recorrer 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 tienen diferentes características de rendimiento.
// Usando NSEnumerator NSEnumerator * enumerator = [ thePeople objectEnumerator ]; Persona * p ;while (( p = [ enumerator nextObject ]) ! = nil ) { NSLog ( @ "% @ tiene% i años." , [ p name ], [ p age ]); }
// Utilización de índices para ( int i = 0 ; i < [ thepeople recuento ]; i ++ ) { Persona * p = [ thepeople objectAtIndex : i ]; NSLog ( @ "% @ tiene% i años." , [ P name ], [ p age ]); }
// Usando enumeración rápida para ( Person * p en thePeople ) { NSLog ( @ "% @ tiene% i años." , [ P name ], [ p age ]); }
La enumeración rápida genera un código más eficaz que la enumeración estándar porque las llamadas a métodos para enumerar objetos se reemplazan por aritmética de puntero mediante el protocolo NSFastEnumeration. [40]
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 usa principalmente como una alternativa a una categoría para agregar métodos a una clase sin publicitarlos en los encabezados públicos, con la ventaja de que para las extensiones de clase, el compilador verifica que todos los métodos declarados de forma privada estén realmente implementados. [41]
Implicaciones para el desarrollo del cacao
Todas las aplicaciones Objective-C desarrolladas para macOS que hacen uso de las mejoras anteriores para Objective-C 2.0 son incompatibles con todos los sistemas operativos anteriores a 10.5 (Leopard). Dado que la enumeración rápida no genera exactamente los mismos binarios que la enumeración estándar, su uso hará que una aplicación se bloquee en Mac OS X versión 10.4 o anterior.
Bloques
Blocks es una extensión no estándar para Objective-C (y C y C ++ ) que usa una sintaxis especial para crear cierres . Los bloques solo son compatibles 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. [42]
#include #include typedef int ( ^ IntBlock ) ();IntBlock MakeCounter ( int inicio , int incremento ) { __block int i = start ;return Block_copy ( ^ { int ret = i ; i + = incremento ; 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 * /
Objective-C moderno
Apple ha agregado algunas características adicionales a Objective 2.0 con el tiempo. Las adiciones solo se aplican al " compilador LLVM de Apple ", es decir, la interfaz de usuario del lenguaje. De manera confusa, el control de versiones utilizado por Apple difiere del de LLVM en sentido ascendente; consulte las versiones de Xcode § Toolchain para obtener una traducción a los números de versión LLVM de código abierto. [43]
Recuento automático de referencias
El recuento automático de referencias (ARC) es una función en tiempo de compilación que elimina la necesidad de que los programadores gestionen manualmente los recuentos retenidos mediante retain
y release
. [44] 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 recuentos de retención. La gestión de memoria ARC y manual no se excluyen mutuamente; Los programadores pueden continuar usando código que no sea 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 el compilador 3.0 de Apple LLVM. [45]
Literales
NeXT y tiempos de ejecución de Apple Obj-C han incluido mucho tiempo una forma de formato corto para crear nuevas cadenas, utilizando la sintaxis literal @"a new string"
, o dejar a las constantes CoreFoundation kCFBooleanTrue
y kCFBooleanFalse
para NSNumber
con los valores booleanos. El uso de este formato evita que el programador tenga que utilizar initWithString
métodos más largos o similares al realizar determinadas operaciones.
Cuando se utiliza de Apple LLVM compilador 4.0 (Xcode 4.4) o posterior, matrices, diccionarios, y los números ( NSArray
, NSDictionary
, NSNumber
clases) pueden también ser creadas usando la sintaxis literal en lugar de métodos. [46] (El compilador 4.0 de LLVM de Apple se traduce en LLVM de código abierto y Clang 3.1.) [47]
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 = @ [ objeto1 , objeto2 , objeto3 ] ; NSDictionary * myDictionary1 = @ { @ "clave" : algúnObjeto } ; NSDictionary * myDictionary2 = @ { clave1 : objeto1 , clave2 : objeto2 } ; NSNumber * myNumber = @ ( myInt ) ; NSNumber * mySumNumber = @ ( 2 + 3 ) ; NSNumber * myBoolNumber = @YES ; NSNumber * myIntegerNumber = @ 8 ;
Sin embargo, a diferencia de los literales de cadena , que se compilan en constantes en el ejecutable, estos literales se compilan en un código equivalente a las llamadas al método anteriores. En particular, en la gestión de memoria contada manualmente por referencia, estos objetos se liberan automáticamente, lo que requiere un cuidado adicional cuando, por ejemplo, se utilizan con variables estáticas de función u otros tipos de globales.
Suscripción
Cuando se usa el compilador Apple LLVM 4.0 o posterior, las matrices y diccionarios ( NSArray
y NSDictionary
clases) se pueden manipular mediante subíndices. [46] El subíndice se puede usar para recuperar valores de índices (matriz) o claves (diccionario), y con objetos mutables, también se puede usar para establecer objetos en índices o claves. En el código, el subíndice se representa mediante corchetes [ ]
. [48]
Ejemplo sin subíndice:
id object1 = [ someArray objectAtIndex : 0 ]; id object2 = [ someDictionary objectForKey : @ "clave" ]; [ someMutableArray replaceObjectAtIndex : 0 withObject : object3 ]; [ someMutableDictionary setObject : object4 forKey : @ "key" ];
Ejemplo con subíndice:
id object1 = someArray [ 0 ]; id object2 = someDictionary [ @ "clave" ]; someMutableArray [ 0 ] = objeto3 ; someMutableDictionary [ @ "clave" ] = objeto4 ;
Sintaxis de Objective-C "moderna" (1997)
Después de la compra de NeXT por parte de Apple, se intentó hacer que el lenguaje fuera más aceptable para los programadores más familiarizados con Java que Smalltalk. Uno de estos intentos fue introducir lo que se denominó "Sintaxis moderna" para Objective-C en ese momento [49] (a diferencia de la sintaxis "clásica" actual). No hubo ningún cambio en el comportamiento, esto fue simplemente 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 . etiquetas ( param1 , param2 );
Del mismo modo, las declaraciones pasaron de la forma
- ( void ) firstLabel : ( int ) param1 secondLabel : ( int ) param2 ;
a
- ( vacío ) etiquetas ( int param1 , int param2 );
Esta sintaxis "moderna" ya no se admite en los dialectos actuales del lenguaje Objective-C.
mulle-objc
El proyecto mulle-objc es otra reimplementación de Objective-C. Es compatible con compiladores GCC o Clang / LLVM como backends. Se diferencia de otros tiempos de ejecución en términos de sintaxis, semántica y compatibilidad ABI. Es compatible con Linux, FreeBSD y Windows.
Compilador de objetos portátil
Además de la implementación de GCC / NeXT / Apple , que agregó varias extensiones a la implementación original de Stepstone , también existe otra implementación gratuita de Objective-C de código abierto llamada Portable Object Compiler. [50] El conjunto de extensiones implementadas por Portable Object Compiler difiere de la implementación GCC / NeXT / Apple; en particular, incluye bloques similares a Smalltalk para Objective-C, mientras que carece de protocolos y categorías, dos características que se utilizan ampliamente en OpenStep y sus derivados y parientes. En general, POC representa una etapa anterior a la siguiente en la evolución del lenguaje, más o menos conforme al libro de Brad Cox de 1991.
También incluye una biblioteca en tiempo de ejecución llamada ObjectPak, que se basa en la biblioteca ICPak101 original de Cox (que a su vez deriva de la biblioteca de la clase Smalltalk-80), y es radicalmente diferente de OpenStep FoundationKit.
Objetivo GEOS-C
El sistema PC GEOS utilizó un lenguaje de programación conocido como GEOS Objective-C o goc ; [51] a pesar de la similitud de nombres, los dos idiomas son similares solo en concepto general y en el uso de palabras clave con el prefijo @.
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) cambiara a GPLv3, Apple lo abandonó en favor de clang, un compilador que tiene más poder legal para modificar. Como resultado, muchas de las características modernas del lenguaje Objective-C solo son compatibles con Clang.
El esquema de control de versiones de Apple para su "compilador LLVM" basado en clang difiere del control de versiones de código abierto de LLVM. Ver versiones de Xcode § Toolchain para una traducción [43]
GNU, GNUstep y WinObjC
El proyecto GNU ha estado interesado durante mucho tiempo en una plataforma para portar programas NeXT y Obj-C. El ChangeLog para El directorio libobjc en GCC sugiere que existió antes de 1998 (GCC 2.95), y su README apunta a una reescritura en 1993 (GCC 2.4). [52]
El código fuente de la interfaz NeXT fue lanzado ya que se creó como parte de GCC, la licencia pública GNU lanzada, lo que obliga a los que realizan trabajos derivados a hacerlo. [ cuando? ] Apple continuó con esta tradición al lanzar su bifurcación de GCC hasta 4.2.1, después de lo cual abandonaron el compilador. Los encargados de mantenimiento de GCC aceptaron los cambios, pero no invirtieron mucho en admitir funciones más nuevas, como el lenguaje Objective-C 2.0. [32] ( Qué compilador )
Los desarrolladores de GNUstep, interesados en el nuevo lenguaje, bifurcaron el GCC libobjc a un proyecto independiente de GCC llamado libobjc2 en 2009. También organizaron que el tiempo de ejecución se usara con Clang para aprovechar la nueva sintaxis del lenguaje. [32] ( Qué compilador ) GCC se movió lentamente al mismo tiempo, pero en GCC 4.6.0 (2011) también se movieron a Objective-C 2.0 en su libobjc. [31] [53] La documentación de GNUstep sugiere que la implementación de GCC aún carece de soporte para bloques, variables no frágiles y el ARC más nuevo. [32] ( Qué tiempo de ejecución )
Microsoft bifurcó libobjc2 en una parte de WinObjC , el puente iOS para la plataforma universal de Windows , en 2015. Combinado con su propia implementación de Cocoa Touch y las API subyacentes, el proyecto permite la reutilización del código de la aplicación iOS dentro de las aplicaciones para UWP. [54]
En Windows, las herramientas de desarrollo de Objective-C se proporcionan para su descarga en el sitio web de GNUStep. El sistema de desarrollo GNUStep consta de los siguientes paquetes: GNUstep MSYS System, GNUstep Core, GNUstep Devel, GNUstep Cairo, ProjectCenter IDE (como Xcode, pero no tan complejo), Gorm (Interface Builder como Xcode NIB builder). Estos instaladores binarios no se han actualizado desde 2016, [55] por lo que podría ser una mejor idea simplemente instalar compilando bajo Cygwin o MSYS2 .
Uso de la biblioteca
En la actualidad, Objective-C se usa a menudo junto con una biblioteca fija de objetos estándar (a menudo conocida como "kit" o "marco"), como Cocoa , GNUstep u ObjFW . Estas bibliotecas a menudo vienen con el sistema operativo: las bibliotecas GNUstep a menudo vienen con distribuciones basadas en Linux y Cocoa viene con macOS. El programador no está obligado a heredar la funcionalidad de la clase base existente (NSObject / OFObject). Objective-C permite la declaración de nuevas clases raíz que no heredan ninguna funcionalidad existente. Originalmente, los entornos de programación basados en Objective-C generalmente ofrecían 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 sobre Object (un énfasis en el uso de referencias de objetos y recuento de referencias en lugar de punteros sin procesar, por ejemplo). Casi todas las clases de 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 permitió que el código que usaba Object, la clase base original usada en NeXTSTEP (y, más o menos, otras bibliotecas de clases Objective-C), coexistir en el mismo tiempo de ejecución con el código que usó NSObject (con algunas limitaciones). La introducción del prefijo de dos letras también se convirtió en una forma simplista de espacios de nombres, que Objective-C carece. 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 Objective-C y continúa hasta el día de hoy.
Más recientemente, han comenzado a aparecer administradores de paquetes, como CocoaPods , que pretende ser tanto un administrador de paquetes como un repositorio de paquetes. Una gran cantidad de código Objective-C de código abierto que se escribió en los últimos años ahora se puede instalar con CocoaPods.
Análisis del idioma
Las implementaciones de Objective-C usan un sistema de ejecución delgado escrito en C [ cita requerida ] , que agrega poco al tamaño de la aplicación. Por el contrario, la mayoría de los sistemas orientados a objetos en el momento de su creación utilizaban tiempos de ejecución grandes de máquinas virtuales . Los programas escritos en Objective-C tienden a no ser mucho 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), en contraste con los sistemas Smalltalk donde se almacenaba una gran cantidad de memoria. usado solo para abrir una ventana. Las aplicaciones de Objective-C tienden a ser más grandes que las aplicaciones de C o C ++ similares porque la escritura dinámica de Objective-C no permite que los métodos se eliminen o se inserten. Dado que el programador tiene tanta libertad para delegar, reenviar llamadas, crear selectores sobre la marcha y pasarlos al sistema de tiempo de ejecución, el compilador de Objective-C no puede asumir que es seguro eliminar métodos no utilizados o llamadas en línea.
Del mismo modo, el lenguaje se puede implementar sobre los compiladores de C existentes (en GCC , primero como preprocesador, luego como módulo) en lugar de como un nuevo compilador. Esto permite que Objective-C aproveche la enorme colección existente de código C, bibliotecas, herramientas, etc. Las bibliotecas C existentes se pueden empaquetar en contenedores Objective-C para proporcionar una interfaz estilo OO. En este aspecto, es similar a la biblioteca GObject y al lenguaje Vala , que se utilizan ampliamente en el desarrollo de aplicaciones GTK .
Todos estos cambios prácticos redujeron la barrera de entrada , probablemente 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 tiene soporte de lenguaje para espacios de nombres . En cambio, los programadores se ven obligados a agregar prefijos a sus nombres de clases, que tradicionalmente son más cortos que los nombres de espacios de nombres y, por lo tanto, más propensos a colisiones. A partir de 2007, todas las clases y funciones de macOS en el entorno de programación Cocoa tienen el prefijo "NS" (por ejemplo, NSObject, NSButton) para identificarlas como pertenecientes al núcleo de macOS o iOS; el "NS" se 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 . También a diferencia de C ++, Objective-C permite que un objeto herede directamente solo de una clase (prohibiendo la herencia múltiple ). Sin embargo, en la mayoría de los casos, se pueden utilizar categorías y protocolos como formas alternativas de lograr los mismos resultados.
Debido a que Objective-C usa tipado dinámico en tiempo de ejecución y debido 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: inlining, propagación constante, optimizaciones entre procedimientos, y reemplazo escalar de agregados). Esto limita el rendimiento de las abstracciones de Objective-C en relación con abstracciones similares en lenguajes como C ++, donde tales optimizaciones son posibles.
Gestión de la memoria
Las primeras versiones de Objective-C no admitían la recolección de basura . En ese momento, esta decisión fue un tema de debate, y muchas personas consideraron que los "tiempos muertos" (cuando Smalltalk realizaba la recolección) inutilizaban todo el sistema. Algunas implementaciones de terceros han agregado esta característica (más notablemente GNUstep usando Boehm ), y Apple la ha implementado a partir de Mac OS X v10.5 . [56] Sin embargo, en versiones más recientes de macOS e iOS, la recolección de basura ha quedado obsoleta en favor del Conteo automático de referencias (ARC), introducido en 2011.
Con ARC, las inserciones del compilador retienen y liberan llamadas automáticamente en el código Objective-C basándose en el análisis de código estático . La automatización libera al programador de tener que escribir código de gestión de memoria. ARC también agrega referencias débiles al lenguaje Objective-C. [57]
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 viene con una gran biblioteca estándar que incluye varias clases de contenedores . De manera similar, Objective-C agrega programación orientada a objetos , escritura dinámica y reflexión a C. Objective-C no proporciona una biblioteca estándar per se , pero en la mayoría de los lugares donde se usa Objective-C, se usa con un OpenStep- like biblioteca como OPENSTEP , Cocoa o GNUstep , que proporciona una funcionalidad similar a la biblioteca estándar de C ++.
Una diferencia notable es que Objective-C proporciona soporte de tiempo de ejecución para características reflectantes , mientras que C ++ agrega solo una pequeña cantidad de soporte de tiempo de ejecución a C.En Objective-C, un objeto puede ser consultado sobre sus propias propiedades, por ejemplo, si responderá a cierto mensaje. En C ++, esto no es posible sin el uso de bibliotecas externas.
El uso de la reflexión es parte de la distinción más amplia entre características dinámicas (tiempo de ejecución) y características estáticas (tiempo de compilación) de un lenguaje. Aunque Objective-C y C ++ emplean cada uno una combinación de ambas características, Objective-C está decididamente orientado a decisiones en tiempo de ejecución, mientras que C ++ está orientado a decisiones en tiempo de compilación. La tensión entre la programación dinámica y estática involucra muchas de las concesiones clásicas en la programación: las características dinámicas agregan flexibilidad, las características estáticas agregan velocidad y verificación de tipos.
La programación genérica y la metaprogramación se pueden implementar en ambos lenguajes utilizando polimorfismo en tiempo de ejecución . En C ++, esto toma la forma de funciones virtuales e identificación de tipo en tiempo de ejecución , mientras que Objective-C ofrece escritura y reflexión dinámicas. Tanto Objective-C como C ++ admiten polimorfismo en tiempo de compilación ( funciones genéricas ), y Objective-C solo agregó esta función en 2015.
Ver también
- C (lenguaje de programación)
- C ++
- Comparación de lenguajes de programación
- Comparación con COM, GObject, SOM, Windows Runtime, XPCOM
- Rápido
- Xcode
- WinObjC (también conocido como Microsoft Bridge para iOS)
Referencias
- ^ "Versiones y plataformas en tiempo de ejecución" . Developer.apple.com . Archivado desde el original el 20 de julio de 2016 . Consultado el 24 de diciembre de 2017 .
- ^ Lattner, Chris (3 de junio de 2014). "Página de inicio de Chris Lattner" . Chris Lattner. Archivado desde el original el 4 de junio de 2014 . Consultado el 3 de junio de 2014 .
El lenguaje Swift es el producto del esfuerzo incansable de un equipo de expertos en lenguaje, gurús de la documentación, ninjas de optimización de compiladores y un grupo interno de prueba interna increíblemente importante que brindó comentarios 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, extrayendo ideas de Objective-C, Rust, Haskell, Ruby, Python, C #, CLU y demasiados otros para enumerarlos.
- ^ "Marcos de aplicaciones" . Manzana. Junio de 2014. Archivado desde el original el 16 de febrero de 2019 . Consultado el 13 de febrero de 2019 .
- ^ Singh, Amit (diciembre de 2003). "Una breve historia de Mac OS X" . Funciones internas de Mac OS X Archivado desde el original el 14 de mayo de 2012 . Consultado el 11 de junio de 2012 .
- ^ Garling, Caleb. "El lenguaje de codificación de iPhone ahora es el tercero más popular del mundo" . Cableado . Archivado desde el original el 9 de septiembre de 2013 . Consultado el 20 de mayo de 2013 .
- ^ Wentk, Richard (2009). Cocoa: Volumen 5 de Developer Reference Apple Developer Series . John Wiley e hijos. ISBN 978-0-470-49589-6. Archivado desde el original el 16 de febrero de 2017 . Consultado el 22 de julio de 2016 .
- ^ Biancuzzi, Federico; Warden, Shane (2009). Mentes maestras de la programación . O'Reilly Media, Inc. págs. 242–246. ISBN 978-0-596-51517-1. Archivado desde el original el 17 de febrero de 2017 . Consultado el 22 de julio de 2016 .
- ^ Cox, Brad (1983). "El precompilador orientado a objetos: programación de métodos Smalltalk 80 en lenguaje C" . Avisos ACM SIGPLAN . Nueva York, NY: ACM . 18 (1). doi : 10.1145 / 948093.948095 . S2CID 6975032 . Consultado el 17 de febrero de 2011 .
- ^ "Common Lisp y Readline" . Archivado desde el original el 6 de septiembre de 2014 . Consultado el 15 de septiembre de 2014 .
El problema surgió por primera vez cuando NeXT propuso distribuir un GCC modificado en dos partes y dejar que el usuario los vincule. Jobs me preguntó si esto era legal. Me pareció en ese momento que sí, siguiendo un razonamiento como el que estás usando; pero como el resultado era muy indeseable para el software libre, dije que tendría que preguntarle al abogado. Lo que dijo el abogado me sorprendió; Dijo que los jueces considerarían tales esquemas como "subterfugios" y serían muy duros con ellos. Dijo que un juez preguntaría si es "realmente" un programa, en lugar de cómo se etiqueta. Así que volví a 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 una interfaz de Objective C. Querían distribuir el analizador de Objective C como un paquete propietario separado para vincularlo con el back-end de GCC, pero como no estaba de acuerdo en que esto estuviera permitido, lo hicieron gratis.
- ^ "GNUstep: Introducción" . Desarrolladores GNUstep / Proyecto GNU. Archivado desde el original el 6 de agosto de 2012 . Consultado el 29 de julio de 2012 .
- ^ "Kresten Krab Thorup | LinkedIn" . www.linkedin.com . Archivado desde el original el 15 de julio de 2014 . Consultado el 23 de junio de 2016 .
- ^ "Escribir código Objective-C" . apple.com. 23 de abril de 2013. Archivado desde el original el 24 de diciembre de 2013 . Consultado el 22 de diciembre de 2013 .
- ^ "Campo de entrenamiento de Objective-C" . Archivado desde el original el 11 de febrero de 2018 . Consultado el 11 de febrero de 2018 .
Objective-C es un superconjunto estricto de ANSI C
- ^ "Examinando Objective-C" . Archivado desde el original el 4 de septiembre de 2014 . Consultado el 4 de septiembre de 2014 .
Objective-C es un superconjunto estricto orientado a objetos de C
- ^ Lee, Keith (3 de septiembre de 2013). Pro Objective-C . Presione. ISBN 9781430250500. Archivado desde el original el 14 de mayo de 2018 . Consultado el 24 de diciembre de 2017 , a través de Google Books.
- ^ "Etiquetas para encabezados Objective-C" . Archivado desde el original el 1 de abril de 2017 . Consultado el 11 de febrero de 2018 .
Objective-C es un superconjunto de C
- ^ "AppScan Source 8.7 ya está disponible" . Archivado desde el original el 3 de febrero de 2017 . Consultado el 11 de febrero de 2018 .
El lenguaje de programación Objective-C es un superconjunto del lenguaje de programación C
- ^ Apple, Inc. (19 de octubre de 2009). "Resolución de método dinámico" . Guía de programación en tiempo de ejecución de Objective-C . Archivado desde el original el 7 de septiembre de 2010 . Consultado el 25 de noviembre de 2014 .
- ^ Apple, Inc. (19 de octubre de 2009). "Evitar errores de mensajería" . El lenguaje de programación Objective-C . Archivado desde el original el 8 de septiembre de 2010.
- ^ "objc_msgSend - Tiempo de ejecución de Objective-C" . Documentación para desarrolladores de Apple . Consultado el 10 de febrero de 2020 .
- ^ "Mensajería con el tiempo de ejecución GNU Objective-C" . Usando la colección de compiladores GNU (GCC) . Consultado el 10 de febrero de 2020 .
- ^ "Categoría" . Desarrollador de Apple (Competencias de Cocoa Core) .
- ^ Dalrymple, Mark; Knaster, Scott (27 de junio de 2012). Aprenda Objective-C en Mac . pag. 9. ISBN 9781430241881.
La extensión .m originalmente significaba "mensajes" cuando se introdujo por primera vez Objective-C, en referencia a una característica central de Objective-C
- ^ "Guía de programación de Objective-C Runtime" . Apple Inc. Archivado desde el original el 4 de abril de 2014 . Consultado el 21 de octubre de 2013 .
- ^ "ACM SIGGRAPH 1983 Edición 8 - Smalltalk" . Archivado desde el original el 15 de abril de 2009 . Consultado el 7 de octubre de 2008 .
- ^ "Métodos de extensión (Guía de programación de C #)" . Microsoft. Octubre de 2010. Archivado desde el original el 11 de julio de 2011 . Consultado el 10 de julio de 2011 .
- ^ "Usando C ++ con Objective-C" . Biblioteca de Referencia Mac OS X . Archivado desde el original el 5 de septiembre de 2010 . Consultado el 10 de febrero de 2010 .
- ^ "Extensiones de lenguaje Clang - Documentación de Clang 3.5" . Clang.llvm.org. Archivado desde el original el 24 de febrero de 2014 . Consultado el 16 de abril de 2014 .
- ^ "Objective-C 2.0: más pistas" . Lists.apple.com. 10 de agosto de 2006. Archivado desde el original el 18 de junio de 2009 . Consultado el 30 de mayo de 2010 .
- ^ "Re: Objective-C 2.0" . Lists.apple.com. Archivado desde el original el 24 de noviembre de 2010 . Consultado el 30 de mayo de 2010 .
- ^ a b "GCC 4.6 Release Series - Cambios, nuevas características y correcciones: Proyecto GNU: Free Software Foundation" . Gcc.gnu.org . Archivado desde el original el 5 de enero de 2018 . Consultado el 24 de diciembre de 2017 .
- ^ a b c d "Preguntas frecuentes sobre ObjC2" . GNUstep . Consultado el 6 de enero de 2020 .
- ^ "Explorador de fuentes: objc4, 756.2" . Código abierto de Apple . Consultado el 6 de enero de 2020 .
- ^ Garbage Collection Programming Guide: Garbage Collection API Archivado el 5 de junio de 2012 en WebCite (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 desde el original el 5 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 desde el original el 24 de julio de 2010 . Consultado el 30 de mayo de 2010 .
- ^ "Transición a las notas de la versión ARC" . Apple Inc. 17 de julio de 2012. Archivado desde el original el 5 de junio de 2012 . Consultado el 26 de agosto de 2012 .
- ^ Mike Ash. "Viernes Q&A 2013-09-27: ARM64 y usted" . mikeash.com. Archivado desde el original el 26 de abril de 2014 . Consultado el 27 de abril de 2014 .
- ^ "Hamster Emporium: [objc explicar]: no puntero isa" . Sealiesoftware.com. 24 de septiembre de 2013. Archivado desde el original el 3 de junio de 2014 . Consultado el 27 de abril de 2014 .
- ^ Apple, Inc. (2009). "Enumeración rápida" . apple.com. Archivado desde el original el 17 de diciembre de 2009 . Consultado el 31 de diciembre de 2009 .
- ^ Fundación de Software Libre, Inc. (2011). "Serie de versiones GCC 4.6 - Cambios, nuevas funciones y correcciones" . Gcc.gnu.org . Archivado desde el original el 2 de diciembre de 2013 . Consultado el 27 de noviembre de 2013 .
- ^ "Temas de programación de bloques - Biblioteca de desarrolladores de Mac" . Apple Inc. 8 de marzo de 2011. Archivado desde el original el 5 de junio de 2012 . Consultado el 28 de noviembre de 2012 .
- ^ a b "Recuento automático de referencias de Objective-C (ARC) - documentación de Clang 11" . Documentación de Clang . Consultado el 20 de febrero de 2020 .
Por ahora, es sensato versionar este documento por los lanzamientos 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 proporcionada por Apple del compilador LLVM de Apple.
- ^ "Transición a ARC" . Apple Inc. Archivado desde el 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 .
- ^ a b "Programación con Objective-C: valores y colecciones" . Apple Inc. Archivado desde el original el 7 de septiembre de 2011 . Consultado el 8 de octubre de 2012 .
- ^ "Notas de la versión de Clang 3.1" . releases.llvm.org .
- ^ "Literales de Objective-C - documentación de Clang 3.5" . Clang.llvm.org. Archivado desde el original el 6 de junio de 2014 . Consultado el 16 de abril de 2014 .
- ^ Guía del desarrollador de Rhapsody , AP Professional, 1997, págs. 76–84
- ^ "Compilador de objetos portátiles" . Users.pandora.be. 1 de enero de 1970. Archivado desde el original el 2 de agosto de 2008 . Consultado el 30 de mayo de 2010 .
- ^ "Página de inicio de Breadbox Computer Company LLC" . Archivado desde el original el 27 de julio de 2011 . Consultado el 8 de diciembre de 2010 .
- ^ "gcc / libobjc" . GitHub . gcc-mirror. 6 de enero de 2020 . Consultado el 6 de enero de 2020 .
El tiempo de ejecución se ha reescrito por completo en gcc 2.4. El tiempo de ejecución anterior tenía varios errores graves y estaba bastante incompleto.
- ^ "API de tiempo de ejecución GNU Objective-C" . Usando GCC . Consultado el 6 de enero de 2020 .
- ^ "WinObjC en GitHub" . Archivado desde el original el 2 de diciembre de 2017 . Consultado el 13 de febrero de 2018 .
- ^ "Instalador GNUStep" . Archivado desde el original el 17 de febrero de 2018 . Consultado el 14 de febrero de 2018 .
- ^ Apple, Inc. (22 de agosto de 2006). "Mac OS X Leopard - Xcode 3.0" . apple.com. Archivado desde el original el 24 de octubre de 2007 . Consultado el 22 de agosto de 2006 .
- ^ "Transición a las notas de la versión ARC" . Biblioteca para desarrolladores de iOS . Developer.apple.com. Archivado desde el original el 7 de septiembre de 2011 . Consultado el 16 de abril de 2014 .
Otras lecturas
- Cox, Brad J. (1991). Programación orientada a objetos: un enfoque evolutivo . Addison Wesley. ISBN 0-201-54834-8.
enlaces externos
- Programando con Objective-C , de Apple (2012-12-13)
- El lenguaje de programación Objective-C , de Apple (2011-10-11)
- Guía de programación en tiempo de ejecución de Objective-C , de Apple (2009-10-19)
- Manual de programación base de Objective-C GNUstep
- Objective-C por Brad Cox
- Preguntas frecuentes de Objective-C