El lenguaje Objetive-C es un lenguaje de programación sencillo diseñado para permitir la programación orientada a objetos. Objetive-C es una extensión del lenguaje estándar ANSI C, proporcionando sintaxis para definir clases y métodos, así como elementos que promueven la extensión dinámicas de clases.
Si has programado alguna vez con lenguajes orientados a objetos, la siguiente información te ayudará a aprender la sintaxis básica de Objetive-C. Muchos de los conceptos tradicionales orientados a objetos, como encapsulación, herencia y polimorfismo, están presentes en Objetive-C. Hay algunas diferencias importantes, pero están citadas en este documento y existe información más detallada si fuera necesario.
Si nunca antes has programado usando un lenguaje orientado a objetos, necesitarás antes tener un conocimiento básico de los conceptos asociados. El uso de objetos y el diseño de patrones orientados a objetos es fundamental para la creación de aplicaciones Cocoa, y comprender cómo interactúan es fundamental para crear sus aplicaciones. Para una visión general de los conceptos puedes ver Programación orientadas a objetos con Objetive-C. También la Guía de fundamentos de Cocoa para obtener información sobre los patrones de diseño utilizados en Cocoa.
Para detalles completos sobre el lenguaje Objetive-C y su sintaxis, consulta El lenguaje de programación Objetive-C
Objetive-C es un superconjunto de la versión ANSI del lenguaje de programación C y soporta la misma sintaxis básica que C. Al igual que el código de C, se definen ficheros de cabecera y ficheros de código para separar las declaraciones públicas de los detalles de implementación del código.
Extensiones de los ficheros para el código de Objetive-C
.h Ficheros cabecera. Contienen las clases, tipo, función y las declaraciones constant .m Código fuente. Es la extensión típica usada en el código fuente y puede contener código C y Objetive-C .mm Código fuente. Pueden contener código en C++, además de Objetive-C y C. Sólo se deben usar si realmente hacen referencia a clases C++ o características desde el código Objetive-C
Cuando quieras incluir un fichero cabecera en el código fuente, deberás usar #import, Es como #include, excepto por que se asegura de que el mismo fichero nunca se incluirá más de una vez. En los ejemplos y documentación de Objetive-C prefieren el uso de #import, nosotros deberíamos usarlo también.
Al igual que en la mayoría de los lenguajes orientados a objetos, las clases en Objetive-C ofrecen la construcción básica para encapsular datos en acciones que manipulan esos datos. Un objeto es una instancia en ejecución de una clase y contiene su propia copia en memoria de las variables de instancia declaradas en esa clase junto con punteros a los métodos definidos por la misma.
La especificación de una clase en Objetive-C requiere dos partes: la interfaz y la implementación. La interfaz es la parte que contiene la declaración de la clase y define las variables de instancia y métodos asociados con la clase. Suele ser un fichero .h. La parte de la implementación contiene el código para los métodos de la clase y suele ser un fichero .m.
Declaración de una clase:
En este ejemplo se muestra la sintaxis para declarar una clase llamada "MyClass", que hereda de la clase base "NSObject". La declaración de una clase siempre comienza con directiva del compilador "@interface"y termina con la directiva "@end". A continuación el nombre de la clases y separado por dos puntos el nombre de la clase base de la que hereda. Las variables de instancia (o miembro) de la clase son declaradas en la parte de código delimitado por { y }. Seguido de la declaración de los métodos. A cada variable de instancia o declaración de método le seguirá un punto y coma.
Aunque esta clase sólo declara métodos, las clases también puede declarar propiedades. Esta información se puede ver más abajo.
Cuando almacenamos objetos en variables, siempre se usa un tipo puntero. Objective-C soporta punteros duros y blandos para el almacenamiento de las variables objeto. Los punteros duros o fuertes incluyen el nombre de la clase en la declaración de la variable. Los blandos o suaves usan el tipo id para el objeto en su lugar. Los punteros blandos se usan frecuentemente para recolectores de clases, donde el número exacto de objetos en el recolector es desconocido. Si estás acostumbrado a usar lenguajes ¿estrictos?, podrías pensar que el uso de punteros blandos te causará problemas, pero actualmente tienen una tremenda flexibilidad, permitiendo mayor dinamismo en los programas Objective-C.
En el siguiente ejemplo se muestra como declarar variables duras y blandas:
MyClass *myObject1; //Variable dura id myObject2; //Variable blanda
Observar el * en la primera declaración. En Objetive-C, la referencia a objetos son punteros. Si esto no tiene sentido para ti, no te preocupes, no es necesario ser un experto en punteros para iniciarse en la programación con Objetive-C. Sólo has de recordar poner un * delante del nombre de la variable para las declaraciones duras.
En Objetive-C una clase puede declarar dos tipos de métodos: métodos de instancia y métodos de la clase. Un método de instancia es un método cuya ejecución tiene como ámbito una instancia particular de la clase. En otras palabras, antes de que llames al método, primero debes crear una instancia de la clase. Los métodos de clase, en contrario, no precisan el crear una instancia, pero lo aclararemos más adelante.
La declaración de un método consisten en un identificador de tipo, el tipo de valor que devuelve, una o más palabras clave, y el tipo y nombre de parámetro. La siguiente imagen muestra la declaración del método de instancia insertObject:atIndex:
Esta declaración está precedida de un signo menos (-), que indica que es un método de instancia. El nombre del método (insertObject:atIndex:) es una concatenación de todas las palabras clave, incluyendo los caracteres dos puntos. Los dos puntos declaran la presencia de un parámetro. Si un método no tiene parámetros, omite la primera pareja de dos puntos después de la primera (y única) palabra clave. En este ejemplo, el método tiene dos parámetros.
Cuando quieras llamar a un método, lo haces pasando mensajes a un objeto. El mensaje son las palabras claves del método junto con los parámetros que el método necesite. Todos los mensajes que envíes a un objeto son enviados dinámicamente, facilitando el comportamiento polimórfico de las clases de Objective-C.
Los mensajes están delimitados por corchetes ([ y ]). Dentro de los corchetes, el objeto que recibe el mensaje se encuentra a la izquierda y el mensaje (junto con los parámetros requeridos por el mensaje) en la derecha. Por ejemplo, para enviar un mensaje insertObject:atIndex: a un objeto en la variable myArray debes utilizar la siguiente sintaxis:
[myArray insertObject:anObject atIndex:0];
Para evitar declarar numerosas variables locales en las que almacenar temporalmente resultados, Objective-C te permite anidar mensajes. El valor de retorno de cada mensaje anidado se usa como parámetro, o como destino, de otro mensaje. Por ejemplo, puedes reemplazar cualquiera de las variables usadas en el ejemplo anterior con mensajes que devuelvan los valores. Por lo tanto, si tenías otro objeto llamado myAppObject que tenía métodos para acceder al objeto array y el objeto para insertar en la matriz, podrías escribir el ejemplo anterior de la siguiente manera:
[[myAppObject theArray] insertObject:[myAppObject objectToInsert] atIndex:0];
Objective-C también proporciona una sintaxis de puntos para invocar métodos de acceso. Los métodos de acceso obtienen y modifican el estado de un objeto, y normalmente tienen la forma -(type)propertyName y -(void)setPropertyName:(type). Utilizando la sintaxis punto, puedes reescribir el ejemplo anterior como:
[myAppObject.theArray insertObject:[myAppObject objectToInsert] atIndex:0];
También puedes usar punto para la asignación:
myAppObject.theArray = aNewArray;
Esto es simplemente una sintaxis diferente para escribir:
[myObject setTheArray:aNewArray];
Aunque los ejemplos anteriores envían mensajes a la instancia de una clase, también puedes enviar mensajes a la clase propiamente dicha. Cuando envías mensajes a una clase, el método que especificas debe estar declarado como un método de clase en vez de como un método de instancia. Puedes pensar sobre los métodos de clase que son algo parecidos (pero no exactamente) a los miembros estáticos en las clases c++.
Normalmente, se utilizan los métodos de clase como fábricas de métodos para crear nuevas instancias de la clase o para acceder a cierta parte de información compartida asociada con la clase. La sintaxis de la declaración de un método de clase es idéntica a la de un método de instancia, con una excepción. En vez de usar un menos como signo para el tipo que identifica al método, se usa un signo mas (+).
El siguiente ejemplo muestra como usar un método de clase como una fábrica de métodos para una clase. En este caso, el método array es un método de clase en la clase NSArray y heredado por NSMutableArray que asigna e inicializa una nueva instancia de clase y la devuelve al código.
NSMutableArray *myArray = nil; // nil es básicamente lo mismo que NULL
// Crear un array asignándolo a la variable myArray.
myArray = [NSMutableArray array];
A continuación se muestra la implementación de MyClass del ejemplo anterior. Como la declaración de la clase, la implementación de la clase está definida por dos directivas de compilación, @implementation y @end. Estas directivas proporcionan el ámbito de información que el compilador necesita para asociar los métodos que acompañan a la correspondiente a clase. La definición de un método, por lo tanto, coincide con su correspondiente declaración en la interfaz, con excepción de la inclusión de un bloque de código.
Implementación de una clase
@implementation MyClass - (id)initWithString:(NSString *)aName { if (self = [super init]) { name = [aName copy]; } return self; } + (MyClass *)createMyClassWithString: (NSString *)aName { return [[[self alloc] initWithString:aName] autorelease]; } @end
La declaración de propiedades son una notación conveniente usada para reemplazar la declaración y, opcionalmente, implementación de los métodos de acceso.
Incluye la declaración de propiedades con la declaración de métodos en la interfaz de tu clase. La definición básica utiliza la directiva de compilador @property, seguida del tipo y el nombre de la propiedad. También puedes configurar la propiedad con opciones personalizadas, que definen como se comporta el método de acceso. El siguiente ejemplo muestra unas declaraciones simples de propiedades:
@property BOOL flag; @property (copy) NSString *nameObject; // Copiar el objeto durante la asignación. @property (readonly) UIView *rootView; // Declaración de sólo lectura.
Cada propiedad con permiso de lectura especifica un método con el mismo nombre que la propiedad. Cada propiedad con permiso de escritura especifica un método adicional con la forma setPropertyName:, donde la primera letra del nombre de la propiedad se encuentra en mayúsculas.
En la implementación de la clase, puede usarse la directiva del compilador @synthesize para pedirle al compilador que genere los métodos de acuerdo con la especificación en la declaración:
@synthesize flag; @synthesize nameObject; @synthesize rootView;
Puedes combinar las declaraciones de @synthesize en una sola línea si quieres:
@synthesize flag, nameObject, rootView;
Hablando desde un punto de vista práctico, las propiedades reducen la cantidad de código redundante que necesitas escribir. Por que la mayoría de métodos de acceso están implementados de manera similar, las propiedades eliminan la necesidad de implementar un método de recuperación y asignación para cada propiedad de la clase. En su lugar, especifica el comportamiento que quiere usar en la declaración de la propiedad y luego sintetiza los actuales métodos recuperación y asignación en tiempo de compilación basados en la declaración.
Para más información sobre como declarar propiedades en tus clases, lee la declaración de propiedades en el Lenguaje de Programación Objetive-C
Como un superconjunto de C, Objective-c soporta las mismas especificaciones sobre cadenas de C. En otras palabras, caracteres simples están rodeados de comillas simples y las cadenas de caracteres están rodeadas de comillas dobles. Sin embargo, la mayoría de frameworks de Objective-C no suelen usar strings al estilo de C. En su lugar, la mayoría de frameworks pasan strings en objetos NSString.
La clase NSString proporciona un objeto envoltorio para cadenas que tienen todas las ventajas que espera, incluyendo gestión de memoria para almacenar cadenas de longitud arbitraria, soporte para Unicode, utilidades de formateo del tipo printf, y más. Debido a que las cadenas se usan con mucha frecuencia, Objective-C proporciona un notación reducida para crear objetos NSString desde valores constantes. Para usar esta notación reducida, lo único que tiene que hacer es preceder una cadena rodeada de comillas dobles con el símbolo @, como se muestra en los siguientes ejemplos:
NSString *myString = @"My String\n"; NSString *anotherString = [NSString stringWithFormat:@"%d %s", 1, @"String"]; // Crear una cadena en Objective-C desde una cadena C NSString *fromCString = [NSString stringWithCString:"A C string" encoding:NSASCIIStringEncoding];
Un protocolo declara métodos que pueden ser implementados por cualquier clase. Los protocolos no sons clases por si mismos. Simplemente definen una interfaz que otros objetos son responsables de implementar. se Cuando implementa los métodos de un protocolo en una de sus clases, se dice que su clase se ajusta al protocolo.
Los protocolos son utilizados para especificar la interfaz para objetos delegados. Un objeto delegado es un objeto que actúa en nombre de, o coordinándose con, otro objeto. La mejor manera de entender la relación entre protocolos, delegados, y otros objetos es simplemente verlo con un ejemplo.
La clase UIApplication implementa el comportamiento requerido por una aplicación. En lugar de forzarte a hacer una subclase de UIApplication para recibir simples notificaciones sobre el estado actual de la aplicación, la clase UIApplication entrega estas notificaciones llamando a métodos específicos asignados a un objeto delegado. Un objeto que implementa los métodos del protocolo UIApplicationDelegate pueden recibir estas notificaciones y proporcionar una respuesta apropiada.
La declaración de un protocolo es similar a la declaración de la interfaz de una clase, con la siguientes excepciones, puesto que los protocolos no tienen una clase padre y no definen instancias de clase. El siguiente ejemplo muestra la declaración de un protocolo simple con un único método:
@protocol MyProtocol - (void)myProtocolMethod; @end
En el caso de muchos protocolos delegados, adoptar un protocolo es simplemente heredar la implementación de los métodos definidos por ese protocolo. Hay algunos protocolos que requieren que se diga explícitamente que el protocolo es soportado, y protocolos que se especifican ellos mismos y métodos opcionales. Conforme se vaya avanzando en el desarrollo, se deberá aprender más sobre protocolos, se puede encontrar más información en Protocolos en el Lenguaje de programación Objetive-C
Fuente: Apple Developer
Comentarios
Porque no tengo un Mac
Porque no tengo un Mac que sino me hubiera tirado de cabeza a iniciarme en la programación de los iDevices, que con tutoriales de este calibre da gusto... ¡Que ganas! =(
Por cierto, como siempre un tutorial de 5 estrellas.
PD: Eskema, todo aporte es bienvenido ;)
-----[[7 años en Scenebeta, con la misma ilusión que la del primer día]]----
Veo que te ha gustado el
Veo que te ha gustado el obj-c y que le tienes pillado el truco :) igual ahora seria un buen momento para plantearme crear unos tutos para hacer juegos en 2d con obj-c y opengl viendo que hay gente de calidad y talento :)
Si, está muy interesante...
Si, está muy interesante... Intentaré ir publicando un tutorial por semana, estoy deseando llegar a las aplicaciones ejemplo :)