You are on page 1of 92

Conviertete en Xcoder

Comienza a programar en Mac usando Objetive-C


Por Bert Altenberg, Alex Clarke y Philippe Moughin

Licencia
Copyright 2006 por Bert Altenburg, Alex Clarke and Philippe Mougin. Version 1.14. Liberado bajo la Licencia Creative Commons License: 2.5 Attribution Non-commercial http://creativecommons.org/licenses/by/2.5/ Atribucin: Los licenciantes, Bert Altenburg, Alex Clarke and Philippe Mougin, permiten copiar, modificar y distribuir el trabajo. A cambio, los licenciatarios deben otorgar el crdito a los autores originales. No-comercial: Los licenciantes permiten la copia, modificacin y distribucin del trabajo y usarlo en cursos remunerados o gratuitos. A cambio, los licenciatarios no pueden vender la obra en s, pero sta puede acompaar a otro trabajo que se venda.

Contenido
Introduccin 00: Antes de empezar 01: Un programa es una serie de instrucciones 02: Sin comentarios ? Inaceptable ! 03: Funciones 04: Salida en pantalla 05: Compilacin y ejecucin de un Programa 06: Sentencias condicionales 07: Ejecucin de bucles 08: Programas con entorno grfico 09: Bsqueda de mtodos 10: awakeFromNib 11: Punteros 12: Cadenas de caracteres 13: Arrays 14: Accesorios y Propiedades 15: Gestin de memoria 16: Fuentes de informacin

Become an Xcoder Espaol v1.15

Introduccin
Apple te ofrece todas las herramientas necesarias para desarrollar aplicaciones basadas en Cocoa, de forma gratuita. Este conjunto de herramientas, conocido con el nombre de Xcode, viene incluido con Mac OS X, o puedes bajarlo de la seccin de desarrolladores en el sitio web de Apple. Existen varios buenos libros sobre programacin para Mac, pero asumen que ya tienes experiencia en programacin. Este libro no. Se ensean los conceptos bsicos de programacin, en particular con Objective-C, usando Xcode. Despus de unos 5 captulos, sers capaz de crear un programa bsico, sin una interfaz grfica de usuario (GUI). Despus de unos captulos ms, sabrs cmo crear programas sencillos con un GUI. Cuando hayas terminado de leer este folleto, estars listo para utilizar libros ms avanzados. Tendr que estudiar esos libros tambin, porque hay mucho ms que aprender. Por ahora, sin embargo, no te preocupes porque este libro toma las cosas con calma.

Cmo usar este libro


Como podrs observar, algunos prrafos se muestran en un recuadro como el siguiente: puntos tcnicos Te sugerimos leer cada captulo dos veces (por lo menos). La primera vez pasa la caja de texto. La segunda vez que leas los captulos incluye la caja de texto. Vas a ensayar en la prctica lo que has aprendido y aprenders algunos puntos tcnicos interesantes que hubieran sido distracciones la primera vez. Al utilizar el libro de esta manera, logrars que la inevitable curva de aprendizaje sea una suave pendiente. Este libro contiene docenas de ejemplos, que constan de una o ms lneas de cdigo de programacin. Para asegurarse de que asocies una explicacin a su respectivo ejemplo, cada ejemplo tiene la etiqueta de un nmero colocado entre corchetes, de esta manera: [1]. La mayora de los ejemplos tienen dos o ms lneas de cdigo. A veces, un segundo nmero se utiliza para referirse a una determinada lnea. Por ejemplo, [1.1] se refiere a la primera lnea del ejemplo [1]. En los fragmentos largos de cdigo, ponemos la referencia despus de una lnea de cdigo, de esta manera:
//[1] volumen = base * altura; // [1.1]

La programacin no es un trabajo simple . Se requiere un poco de perseverancia y que t mismo trates de hacer todas las cosas que se ensean en este libro. No se puede aprender a tocar el piano o conducir un coche exclusivamente por la lectura de libros. Lo mismo vale para aprender a programar. Este libro est en un formato electrnico, por lo que no tienes ninguna excusa para utilizar Xcode con frecuencia. Por lo tanto, a partir del captulo 5, te sugerimos que vayas a travs de cada captulo en tres ocasiones. La segunda vez, prueba los ejemplos y haz pequeas modificaciones al cdigo para explorar cmo funcionan las cosas.

Introduccin

Pgina 1 de 1

Become an Xcoder Espaol v1.15

00: Antes de empezar


Escribimos este libro para usted. Como es gratis, por favor permtame decir un par de palabras sobre la promocin de la Mac a cambio. Cada usuario de Macintosh puede ayudar a promover su plataforma preferida con un poco esfuerzo. Aqu es cmo. Cuanto ms eficiente con la Mac sea usted, ms fcil es llevar a otras personas a considerar una Mac. Por lo tanto, tratar de estar al da visitando sitios web orientados a la Mac y leer revistas de Mac. Por supuesto, el aprendizaje de Objective-C o AppleScript y ponerlos en uso es bueno tambien. Para las empresas, el uso de AppleScript puede ahorrar toneladas de dinero y tiempo. Echa un vistazo al folleto gratis de Bert, AppleScript Absolutos para Principiantes, disponible en: http://www.macscripter.net/books Muestrale al mundo que no todo el mundo est usando una PC, haciendo la Macintosh ms visible. El uso de una camiseta en pblico con el logo de Mac es una manera, pero hay otras maneras, puede hacer que el Mac sea ms visibles dentro de su hogar. Si ejecuta Activity Monitor (en la carpeta Utilidades, que se encuentra en la carpeta de Aplicaciones de tu Mac), te dars cuenta de que tu Mac utiliza todo su poder de procesamiento slo de vez en cuando. Los cientficos han puesto en marcha varios proyectos de informtica distribuida (DC) , como el Folding@home o SETI@home, que aprovechar esta potencia de procesamiento no utilizada, por lo general en pro del bien comn. Usted descarga un pequeo programa gratuito, llamado DC client, y empezara a procesar unidades de trabajo. Estos clientes DC correr con menor nivel de prioridad. Si ests usando un programa en tu Mac y las necesidades del programa requieren plena potencia de procesamiento, el DC client inmediatamente toma menor prioridad. As, usted no notar que est funcionando. Cmo ayuda esto a las Mac? Bueno, la mayora de los proyectos DC mantienen rankings en sus sitios web de las unidades procesadas hasta la fecha. Si se inscribe en un equipo Mac (reconocer sus nombre en los rankings), puede ayudar al equipo Mac de su eleccin para ascender en la clasificacin. As, los usuarios de otras plataformas de ordenador veran que tan bien las Macs estn haciendo. Hay DC clients que se concentran en varios temas, como matemticas, curar enfermedades y mucho ms. Para elegir un proyecto DC que te gusta, echa un vistazo a: http://distributedcomputing.info/projects.html Un problema con esta sugerencia: Se puede llegar a ser adicto! Asegrese de que la plataforma Macintosh tiene el mejor software. No, no slo mediante la creacin de programas propios. Haga un hbito de dar (corts) retroalimentacin a los desarrolladores de programas que usted utiliza. Incluso si trat una pieza de software y no le gusto, expliquele al desarrollador por qu. Asegrese de informar sobre errores y proporcione una descripcin exacta como sea posible de las acciones que realiz cuando se experiment el error.

00: Antes de empezar

Pgina 1 de 2

Become an Xcoder Espaol v1.15

Pagar por el software que usted utiliza. Mientras el mercado de software para Macintosh sea viable, los desarrolladores seguirn proveyendo buen software. Pngase en contacto con al menos 3 usuarios de Macintosh que podran estar interesados en programacin, digales acerca de este libro y dnde encontrarlo. O asesorelos sobre los 4 puntos mencionados arriba. OK, mientras el DC client termina de descargar en el fondo, vamos a empezar!

00: Antes de empezar

Pgina 2 de 2

Become an Xcoder Espaol v1.15

01: Un programa es una serie de instrucciones


Presentacin
Para conducir un automvil, tienes que aprender a controlar varias cosas a la vez. La programacin tambin requiere que mantengas un montn de cosas en mente, o tu programa romper. Mientras que al menos ya conocas el interior de un coche antes de aprender a conducir, no tendrs esa ventaja cuando trates de aprender a programar con Xcode. Para no abrumarte, dejamos el entorno de programacin para un captulo posterior. En primer lugar, vamos a hacer que te sientas cmodo con algunos conceptos de Objective-C, empezando por la matemtica bsica. En la escuela primaria haba que hacer clculos, rellenando los puntos: 2 + 6 = .. .. = 3 * 4 (el asterisco * es la forma estndar para representar la multiplicacin en los teclados de ordenador) En la escuela secundaria, los puntos pasaron de moda y unas variables llamadas 'x' e 'y' (y una nueva palabra: "lgebra") fueron la gran sensacin. Mirando hacia atrs, puede que te preguntes por qu nos hemos sentido tan intimidados en su momento por este pequeo cambio en la notacin.
2 + 6 = x y = 3 * 4

Variables
Objective-C tambin utiliza variables. Las variables no son nada ms que nombres para referirse a unos datos concretos, como por ejemplo un nmero. Aqu tenemos una sentencia Objective-C, es decir, una lnea de cdigo, en la que asignamos un valor a una variable.
//[1] x = 4;

El punto y coma
Se le ha asignado el valor 4 a la variable x. Te habrs dado cuenta de que hay un punto y coma al final de la instruccin. Esto se debe a que se requiere que todas las instrucciones terminen en punto y coma. Por qu? Bien, el trozo de cdigo que hay en el ejemplo [1] puede parecerte sencillo, pero un ordenador no es capaz de comprenderlo. Se necesita un programa especial, llamado compilador, para convertir ese texto en una secuencia de instrucciones que l s sea capaz de entender y ejecutar. Leer y entender nuestro idioma

01: Un programa es una serie de instrucciones

Pgina 1 de 8

Become an Xcoder Espaol v1.15

puede ser muy difcil para un compilador as que debemos darle algunas pistas, por ejemplo: indicarle dnde termina cada sentencia; y eso es lo que hacemos con el punto y coma. Si te olvidas el punto y coma en tu cdigo, ste no se podr compilar, es decir, no se va a poder convertir en un programa que tu Mac pueda ejecutar. No te preocupes ahora de eso, pues el compilador se quejar si hay algn problema y, como veremos en un captulo posterior, intentar ayudarte a encontrar lo que est mal.

Dar nombres a las variables


Mientras que los nombres de las variables no tienen una importancia especial para el compilador, el utilizar nombres descriptivos s que nos puede facilitar la lectura del programa y hacerlo ms comprensible. Ten esto en cuenta para cuando tengas que buscar errores en tu cdigo. Por tradicin se llaman "bugs" (bichos) a los errores de los programas. A la bsqueda y reparacin de bugs se le llama debugging (en espaol solemos decir depuracin). Por tanto, en programas reales evitaremos usar nombres de variables no descriptivos tales como x. Por ejemplo, el nombre de la variable en la que almacenaramos el ancho de un dibujo sera anchoDibujo [2].
//[2] anchoDibujo = 8;

Ahora que sabes que para el compilador es un gran problema que te olvides del punto y coma, comprenders que en la programacin hay que prestar atencin a los detalles. Uno de esos detalles es que el cdigo es sensible a maysculas/minsculas. Es decir, la variable anchoDibujo no es la misma que anchoDIBUJO ni que AnchoDibujo. La convencin que vamos a seguir para los nombres de variables es unir varias palabras, la primera iniciada por minsculas y el resto por maysculas, tal como has visto en el ejemplo [2]. A este estilo se le suele llamar camelCase (se llama as por las jorobas del camello, en ingls camel. Cada mayscula es una joroba). Te ser conveniente seguir este esquema para reducir las posibilidades de cometer errores con los nombres de variables. Ten en cuenta que los nombres de variables consisten en una sola palabra, en el sentido de que no hay espacios en el nombre. Tienes total libertad para elegir el nombre de tus variables, pero hay una serie de reglas que debes seguir: la primera es que no puede ser el nombre de una palabra reservada de Objective-C (palabras que tienen un significado especial para Objective-C). Si tus variables estn compuestas al menos de dos palabras unidas, como por ejemplo anchoDibujo, no vas a tener problema. Para facilitar la lectura se recomienda poner en mayscula la inicial de cada palabra excepto la primera, tal como hemos visto. Sigue este esquema para evitar bugs en tus programas.

01: Un programa es una serie de instrucciones

Pgina 2 de 8

Become an Xcoder Espaol v1.15

Si no te importa aprender un par de reglas ms, sigue leyendo. Tambin se permite el uso de dgitos adems de letras, pero no puedes usar un dgito al comienzo del nombre. Tambin se permite el guin bajo: "_". Vamos a ver ejemplos de nombres de variables. Nombres vlidos de variables:
puerta8k pu3rta puer_ta

Nombres no permitidos:
puerta 8 (porque contiene un espacio) 8puerta (porque empieza por un dgito)

Nombres vlidos pero no recomendados:


Puerta8 (porque empieza por mayscula)

Uso de variables en clculos


Ahora que sabemos como asignar un valor a una variable, podemos hacer clculos. Echemos un vistazo al cdigo para calcular la superficie de un dibujo [3].
//[3] anchoDibujo=8; altoDibujo=6; areaDibujo=anchoDibujo*altoDibujo;

Sorprendentemente, al compilador no le importan los espacios (con la excepcin, como ya sabemos, de que estn prohibidos en los nombres de variables), as que podemos usar todos los que queramos para facilitar la lectura de nuestro cdigo.
//[4] anchoDibujo = 8; altoDibujo = 6; areaDibujo = anchoDibujo * altoDibujo;

Y en un arranque de generosidad, el compilador tambin nos permite introducir saltos de lnea en medio de las instrucciones te imaginas por qu? Pues porque, si recuerdas lo que vimos un poco ms arriba, l va a interpretar todo como una sola instruccin hasta que encuentre el punto y coma (el indicador de fin de instruccin). Podemos usar esta caracterstica para facilitar la lectura en lneas excesivamente largas. As que lo siguiente tambin sera vlido para el compilador (pero tambin bastante incmodo de leer):
anchoDibujo = 8; altoDibujo = 6;

01: Un programa es una serie de instrucciones

Pgina 3 de 8

Become an Xcoder Espaol v1.15

areaDibujo = anchoDibujo * altoDibujo;

Enteros y fraccionarios
Echemos un vistazo al ejemplo [5], especialmente a las dos primeras sentencias.
//[5] anchoDibujo = 8; altoDibujo = 4.5; areaDibujo = anchoDibujo * altoDibujo;

Se pueden distinguir en general dos tipos de nmeros: enteros y fraccionarios. Puedes ver un ejemplo de cada en [5.1] y [5.2] respectivamente. Los enteros se usan para contar, que es algo que haremos cuando queramos realizar una serie de instrucciones un nmero determinado de veces (ver captulo 7). Los nmeros fraccionarios los usamos, por ejemplo, con los precios. Importante: Segn el pas, se usa como carcter separador de la parte decimal el punto "." o la coma ",". En Objective-C debemos emplear obligatoriamente siempre el punto. El cdigo del ejemplo [5] no funcionara. El problema es que el compilador necesita que le indiques previamente el nombre de las variables que vas a usar en tu programa y tambin qu tipo de dato va a contener cada una. Eso es lo que llamamos "declarar una variable".
//[6] int anchoDibujo; // [6.1] float altoDibujo, areaDibujo; // [6.2] anchoDibujo = 8; altoDibujo = 4.5; areaDibujo = anchoDibujo * altoDibujo;

En la lnea [6.1], int indica que la variable anchoDibujo contiene un nmero entero. En la siguiente lnea [6.2] declaramos dos variables con una sola instruccin, separando sus nombres con coma. En la sentencia tambin se indica que son de tipo float, lo que quiere decir que van a ser nmeros con una parte fraccionaria. Llegados a este punto, parece que no tiene sentido que la variable anchoDibujo sea de tipo diferente a las otra dos. Pero lo que sabes es que si multiplicas un int por un float el resultado del clculo es un float, que es la razn por la que deberas declarar la variable areaDibujo como float [6.2]. Por qu quiere el compilador conocer si una variable representa a un nmero entero o a uno fraccionario? Bien, un programa usa parte de la memoria del ordenador y el compilador reserva espacio para cada variable que se declara, pero necesita saber el tipo, ya que cada tipo requiere una cantidad distinta y tambin se representa de forma distinta en la memoria del ordenador. Y si necesitamos trabajar con nmeros muy grandes o con gran precisin de decimales? Van a poder representarse en los tipos que conocemos hasta ahora (int y float)? Bien,
01: Un programa es una serie de instrucciones Pgina 4 de 8

Become an Xcoder Espaol v1.15

esta pregunta tiene dos respuestas: en primer lugar, existen otros tipos de datos para enteros ms grandes (long) y para fraccionarios de ms precisin (double). Pero incluso estos tipos de dato podran no ser suficiente, lo que nos lleva a la segunda respuesta: como programador, parte de tu trabajo es estar atento a los posibles problemas. Pero eso no es un asunto para discutir en el primer captulo de un libro de introduccin. Por cierto, los tipos que hemos visto pueden almacenar tambin nmeros negativos. Si sabes que el valor de tu variable nunca va a ser negativo puedes restringir el rango de valores.
//[7] unsigned int cajasDisponibles;

No tiene sentido que el nmero de cajas disponibles en el almacn sea negativo, as que en este caso podramos usar unsigned int. El tipo unsigned int representa un nmero entero mayor o igual a cero.

Declarar variables
Es posible declarar una variable y asignarle un valor de una vez [8].
//[8] int x = 10; float y= 3.5, z = 42;

Esto te ahorra algo de tecleo.

Tipos de datos
Como ya hemos visto, los datos almacenados en variables pueden ser de varios tipos especficos, por ejemplo int o float. En Objective-C, a los tipos de dato como esos se les llama tambin tipos escalares. A continuacin mostramos una lista con los tipos de dato escalares ms comunes de ObjectiveC: Nombre void int Tipo Vaco Nmero entero Ejemplo Nada ...-1, 0, 1, 2... 0, 1, 2... -0.333, 0.5, 1.223, 202.85556 0.52525252333234093890324592793021 hola

unsigned Nmero entero positivo float double char Nmero fraccionario Nmero fraccionario de doble precisin Carcter

01: Un programa es una serie de instrucciones

Pgina 5 de 8

Become an Xcoder Espaol v1.15

BOOL

Boolean

0, 1; TRUE, FALSE; YES, NO.

Operaciones matemticas
En los ejemplos previos hemos realizado una multiplicacin. Se usan los siguientes smbolos, conocidos oficialmente como "operadores", para realizar clculos matemticos bsicos.
+ / * suma resta divisin multiplicacin

Aparte de estos operadores, si echamos un vistazo al cdigo de un programa en Objective-C, podemos encontrarnos con un par de curiosidades, quiz porque los programadores son unos mecangrafos perezosos. En lugar de escribir x = x + 1;, con frecuencia los programadores recurren a cosas como [9] y [10]
//[9] x++; //[10] ++x;

En cualquiera de los dos casos, lo que significa es: incrementa en 1 el valor de x. En algunas circunstancias es importante situar el ++ antes o despus del nombre de la variable. Fjate en estos ejemplos [11] y [12].
//[11] x = 10; y = 2 * (x++); // "x" tiene aqu el valor 11, pero se le asign DESPUES de realizar el clculo // por tanto "y" tiene el valor 20 //[12] x = 10; y = 2 * (++x); // "x" tambin vale ahora 11, pero su valor se asign ANTES de hacer el clculo // as que "y" vale 22

Si usamos el ++ antes del nombre de la variable, se incrementar su valor antes de emplear la variable en el clculo en el que est envuelta. Si usamos ++ despus del nombre de la variable, se incrementar su valor despus de utilizarse en el clculo en el que est envuelta. El cdigo de [12] es equivalente al de [13].
//[13] x = 10;

01: Un programa es una serie de instrucciones

Pgina 6 de 8

Become an Xcoder Espaol v1.15

x++; // [13.2] y = 2 * x; // Como el incremento de x en la lnea [13.2] no est envuelto en ninguna // operacin, en este caso sera lo mismo usar ++x que x++

Con esto se unen dos sentencias en una, pero quiz pueda hacer un poco ms difcil de entender tu programa. Es correcto emplearlo pero ten en cuenta que puede estar acechando un bug por ah.

Parntesis
Seguro que ya lo sabes, pero los parntesis se pueden utilizar para indicar el orden en el que queremos que se realicen las operaciones. La multiplicacin y divisin tienen precedencia sobre la suma y la resta, as que, por ejemplo, 2 * 3 + 4 es igual a 10. Usando parntesis podemos forzar a que se realice antes la suma que la multiplicacin: 2 * (3 + 4) es igual a 14.

Divisin
La divisin requiere un poco de atencin, ya que tiene un comportamiento distinto segn usemos enteros o fraccionarios. Echa un vistazo a los ejemplos [14] y [15].
//[14] int x = 5, y = 12, ratio; ratio = y / x; //[15] float x = 5, y = 12, ratio; ratio = y / x;

En el primer caso [14], el resultado es 2 Por qu? Al ser enteros el dividendo y el divisor, el resultado tambin es un nmero entero. En el segundo [15], el resultado es el que probablemente te esperas: 2,4

Booleanos
Un booleano (la palabra viene de George Boole, el matemtico inventor de la lgica booleana) es un valor lgico verdadero o falso. Se pueden considerar equivalentes el 1 como valor verdadero y el 0 como valor falso. Verdadero Falso 1 0

Se emplean con frecuencia para determinar si se realiza o no una accin dependiendo del valor booleano de alguna variable o funcin.

Resto (en ingls: modulus)


01: Un programa es una serie de instrucciones Pgina 7 de 8

Become an Xcoder Espaol v1.15

Probablemente no ests tan familiarizado con el operador %, que no tiene que ver con los porcentajes sino que calcula el resto de la divisin entre el primer y el segundo operando (si el segundo operando es 0, el comportamiento de % es indefinido).
//[16] int x = 13, y = 5, resto; resto = x % y;

La variable resto contendr el valor 3. Ms ejemplos de este operador:


21 22 23 24 27 30 31 32 33 34 50 60 % % % % % % % % % % % % 7 es igual a 0 7 es igual a 1 7 es igual a 2 7 es igual a 3 7 es igual a 6 2 es igual a 0 2 es igual a 1 2 es igual a 0 2 es igual a 1 2 es igual a 0 9 es igual a 5 29 es igual a 2

Puede sernos til en ocasiones, pero ten en cuenta que slo funciona con enteros. Uno de los usos ms comunes del operador % es determinar si un nmero es par o impar. Si es par, su resto entre 2 es 0, si es impar entonces ser 1. Por ejemplo:
//[17] int unNumero; //Aqu escribiramos cdigo que asigna un valor a "unNumero" if ((unNumero % 2) == 0) // [17.3] { NSLog(@"unNumero es par"); } else { NSLog(@"unNumero es impar"); }

En la lnea [17.3] se ha empleado un condicional, que vers en el captulo 6. Podramos traducir la instruccin como: "si el resto de la divisin unNumero entre 2 es igual a 0, entonces "

01: Un programa es una serie de instrucciones

Pgina 8 de 8

Become an Xcoder Espaol v1.15

02: Sin comentarios ? Inaceptable !


Introduccin
Si utilizamos nombres de variables con sentido, haremos que nuestro cdigo sea ms legible y entendible [1].
//[1] float anchoDelDibujo, altoDelDibujo, areaDelDibujo; anchoDelDibujo = 8.0; altoDelDibujo = 4.5; areaDelDibujo = anchoDelDibujo * altoDelDibujo;

Hasta ahora nuestros ejemplos de cdigo han sido de slo unas pocas sentencias, pero incluso los programas ms sencillos pueden crecer rpidamente hasta cientos o miles de lneas. Cuando revises tu programa despus de algunas semanas o meses puede ser difcil recordar la razn por la que tomaste ciertas decisiones. Ah es donde entran en accin los comentarios. Los comentarios ayudarn a comprender rpidamente lo que hace cada parte de tu programa y por qu. Algunos programadores van ms all y siempre comienzan a codificar cada clase como comentarios, con lo que se organizan mejor y evitan tener que improvisar cdigo posteriormente. Recomendamos invertir tiempo en comentar el cdigo. Podemos asegurarte que esa inversin ser revertida con creces en el futuro. Tambin, si compartes tu cdigo con alguien ms, tus comentarios ayudarn a que se adapte a tus propias necesidades ms rpidamente.

Crear comentarios
Para indicar el comienzo de un comentario teclea dos barras.
// Esto es un comentario

En Xcode los comentarios se muestran en verde. Si el comentario es largo y ocupa varias lneas, encirralo entre /* */.
/* This is a comment extending over two lines */

Comentar cdigo
Hablaremos sobre la depuracin dentro de poco, ya que Xcode tiene buenas herramientas para ello. Una de las formas de depuracin a la vieja usanza es comentar el cdigo. Comentamos cdigo envolviendo las instrucciones entre /* */, de esta forma deshabilitamos el cdigo, impidiendo su ejecucin y podemos comprobar si el resto funciona como esperbamos. Esto puede ayudarnos a encontrar errores. Si, por ejemplo, la parte de cdigo comentada asigna valores a una variable, podemos aadir una lnea de cdigo

02: Sin comentarios ? Inaceptable !

Pgina 1 de 2

Become an Xcoder Espaol v1.15

temporal que asigne a esa variable un valor que nos sirva para comprobar el resto de nuestro cdigo.

Por qu incluir comentarios?


No debemos desestimar la importancia de los comentarios. Frecuentemente es til incluir explicaciones en nuestro idioma sobre lo que hace una serie de instrucciones. As no hay que estar deduciendo qu es lo que hace esa parte de cdigo y podemos darnos cuenta inmediatamente de si el problema tiene su origen o no en esa seccin. Adems podemos usar los comentarios para explicar cosas difciles o casi imposibles de deducir leyendo el cdigo. Por ejemplo, si programas una funcin matemtica que encontraste detallada en un libro, podras poner la referencia bibliogrfica dentro de un comentario. A veces es til hacer los comentarios antes de escribir el cdigo. Eso ayudar a estructurar tus pensamientos y como resultante la programacin ser mas fluida. Los ejemplos de cdigo que encontrars en este libro no contienen tantos comentarios como generalmente se deberan poner, pero eso es porque ya se dan las explicaciones en el texto que los precede.

02: Sin comentarios ? Inaceptable !

Pgina 2 de 2

Become an Xcoder Espaol v1.15

03: Funciones
Introduccin
El trozo de cdigo ms largo que hemos visto hasta ahora tena slo cinco lneas. Los programas de varias miles de lneas parecen quedarnos an muy lejos, pero debido a la naturaleza de Objective-C, debemos discutir la forma de organizar los programas en esta etapa temprana. Si un programa consistiese en una sucesin larga y continua de instrucciones sera difcil encontrar y reparar errores. Adems, una serie concreta de instrucciones podra aparecer en varias partes de tu programa. Si hubiese en ellas algn error, deberas arreglar el mismo error en varios lugares. Eso sera una pesadilla porque sera fcil olvidarse de uno (o varios). Por tanto, la gente ha pensado una solucin para organizar el cdigo, facilitando la correccin de errores. La solucin a este problema es agrupar las instrucciones dependiendo de la tarea que realicen. Por ejemplo, tienes una serie de instrucciones que calculan el rea de un crculo. Una vez que has comprobado que esas instrucciones funcionan correctamente, nunca tendrs que volver a ese cdigo para examinar si hay algn error en l. El conjunto de instrucciones, llamado funcin (function en ingls), tiene un nombre y puedes llamarlo por ese nombre cada vez que necesites que se ejecute ese cdigo. Este concepto de usar funciones es fundamental, de hecho siempre hay al menos una funcin en un programa: la funcin main(). Esta funcin main() es la que busca el compilador para saber por donde debe empezar la ejecucin del programa.

La funcin main()
Pasemos a estudiar la funcin main() con ms detalle. [1]
//[1] main() { // Cuerpo de la funcin main(). Escribe aqu tu cdigo. }

La sentencia [1.1] muestra el nombre de la funcin, en este caso "main", seguido de la apertura y cierre de parntesis. Es obligatorio que exista esta funcin main(), que por otro lado es una palabra reservada (lo que significa entre otras cosas que no podemos usarla como nombre para nuestras variables). Cuando creemos nuestras funciones podremos darles el nombre que queramos. Los parntesis estn ah por una buena razn, pero la conoceremos ms adelante en este captulo. En las siguiente lneas [1.3, 1.5], hay llaves. Debemos poner nuestro cdigo entre esas llaves { }. Cualquier cosa entre las llaves es lo que llamamos el cuerpo de la funcin. He copiado cdigo del primer captulo y lo he puesto aqu en donde corresponde [2].
//[2]

03: Funciones

Pgina 1 de 6

Become an Xcoder Espaol v1.15

main() { // A continuacin se declaran las variables float anchoDelDibujo, altoDelDibujo, superficieDelDibujo; // Asignamos un valor inicial a las variables anchoDelDibujo = 8.0; altoDelDibujo = 4.5; // Aqu se realiza el clculo superficieDelDibujo = anchoDelDibujo * altoDelDibujo; }

Nuestra primera funcin


Si escribimos todo nuestro cdigo en el cuerpo de la funcin main(), eso nos llevara al problema del cdigo desestructurado y difcil de depurar que queremos evitar. As que escribamos otro programa, ahora con un poco de estructura. Adems de la funcin main() obligatoria crearemos una funcin calculaAreaDelCirculo() [3].
//[3] main() { float anchoDelDibujo, altoDelDibujo, superficieDelDibujo; anchoDelDibujo = 8.0; altoDelDibujo = 4.5; superficieDelDibujo = anchoDelDibujo * altoDelDibujo; } calculaAreaDelCirculo() // [3.9] { }

Ha sido fcil, pero nuestra funcin definida desde la lnea [3.9] an no hace nada. Observa que la especificacin de la funcin est fuera del cuerpo de la funcin main(). En otras palabras, las funciones no estn anidadas. Queremos que nuestra nueva funcin calculaAreaDelCirculo() sea llamada desde la funcin main(). Veamos cmo podemos hacerlo [4].
//[4] main() { float anchoDelDibujo, altoDelDibujo, superficieDelDibujo, radioDelCirculo, superficieDelCirculo; // [4.4] anchoDelDibujo = 8.0; altoDelDibujo = 4.5; radioDelCirculo = 5.0; // [4.7] superficieDelDibujo = anchoDelDibujo * altoDelDibujo; // Aqu es donde llamamos a nuestra funcin! superficieDelCirculo = calculaAreaDelCirculo(radioDelCirculo); // [4.10] }

Nota: no mostramos el resto del programa (ver [3]).

03: Funciones

Pgina 2 de 6

Become an Xcoder Espaol v1.15

Pasar argumentos a la funcin


Hemos aadido un par de nombres de variable de tipo float [4.4], y hemos inicializado la variable radioDelCirculo dndole un valor [4.7]. Tiene ms inters la lnea [4.10], en la que llamamos a la funcin calculaAreaDelCirculo(). Como puedes ver, el nombre de la variable radioDelCirculo se ha puesto entre parntesis. Es un argumento de la funcin calculaAreaDelCirculo(). El valor de la variable radioDelCirculo se pasa a la funcin calculaAreaDelCirculo(). Cuando la funcin calculaAreaDelCirculo() ha hecho su tarea debe devolver un valor, en este caso el resultado del clculo de la superficie. Modifiquemos el cdigo de la funcin calculaAreaDelCirculo() [5]. Nota: slo se muestra el cdigo de la funcin calculaAreaDelCirculo().
//[5] calculaAreaDelCirculo(float radio) // [5.1] { float area; area = 3.1416 * radio * radio; // pi veces el cuadrado del radio [5.4] return area; }

En [5.1] definimos que se requiere un valor de tipo float como entrada para la funcin calculaAreaDelCirculo(). Cuando se recibe, ese valor es almacenado en una variable llamada radio. Usamos una segunda variable, area, para almacenar el resultado del clculo en [5.4], as que la declaramos en [5.3] de la misma forma que hemos declarado variables en la funcin main() [4.4]. Vers que la declaracin de la variable radio se ha hecho dentro de los parntesis [5.1]. La lnea [5.5] devuelve el resultado a la parte del programa desde la que fue llamada esta funcin. Como consecuencia, en la lnea [4.10], se asigna ese valor a la variable superficieDelCirculo. La funcin en el ejemplo [5] est completa, excepto por una cosa. No hemos especificado el tipo de datos que devolver la funcin. El compilador nos va a requerir ese dato, as que no nos queda otra opcin que obedecerle e indicar que es de tipo float [6.1].
//[6] float calculaAreaDelCirculo(float radio) { float area; area = 3.1416 * radio * radio; return area; } //[6.1]

Como indica la primera palabra de la lnea [6.1], el dato devuelto por esta funcin (en este caso el dato devuelto por la variable area), es de tipo float. Como programador, debes asegurarte de que la variable superficieDelCirculo en la funcin main() es tambin de ese tipo, para que el compilador no nos moleste sobre ese asunto.

03: Funciones

Pgina 3 de 6

Become an Xcoder Espaol v1.15

No todas las funciones requieren argumentos. Si no hay ninguno, los parntesis siguen siendo obligatorios, aunque no tengan contenido.
//[7] int tiraElDado() { int numeroDePuntos; // Aqu se escribira cdigo para generar un nmero aleatorio entre 1 y 6 return numeroDePuntos; }

Devolucin de valores
No todas las funciones devuelven un valor. Si una funcin no devuelve un valor, entonces es de tipo void (que significa "vaco"). En este caso, la sentencia return es opcional. Si la usas, entonces la palabra return debe ir sola, sin indicarle a continuacin un valor o nombre de variable.
//[8] void alarmaXVeces(int x); { // Cdigo para hacer que suene la alarma x veces return; }

Si la funcin tiene ms de un argumento, como en la funcin calculaAreaDelDibujo() que est a continuacin, los argumentos van separados por comas (,).
//[9] float calculaAreaDelDibujo(float ancho, float alto) { // Cdigo para calcular la superficie... }

Por convenio, la funcin main() debera devolver un entero y, por tanto, debera tener tambin una sentencia return. Debera devolver 0 (cero, [10.9]) para indicar que todo se ha ejecutado sin problemas. Ya que devuelve un entero, debemos escribir int antes de main() [10.1]. Pongamos junto todo el cdigo que tenemos.
//[10] int main() // [10.1] { float anchoDelDibujo, altoDelDibujo, areaDelDibujo, radioDelCirculo, superficieDelCirculo; anchoDelDibujo = 8; altoDelDibujo = 4.5; radioDelCirculo = 5.0; areaDelDibujo = anchoDelDibujo * altoDelDibujo; superficieDelCirculo = calculaAreaDelCirculo(radioDelCirculo); [10.8] return 0; // [10.9] }

//

03: Funciones

Pgina 4 de 6

Become an Xcoder Espaol v1.15

float calculaAreaDelCirculo(float radio) { float area; // [10.14] area = 3.1416 * radio * radio; return area; }

// [10.12]

Hacer que todo funcione


Como puedes ver en [10], tenemos una funcin main() y otra funcin que hemos definido nosotros mismos [10.12]. Si intentsemos compilar este cdigo, el compilador lo rechazara. En la lnea [10.8] indicara que no conoce ninguna funcin llamada calculaAreaDelCirculo(). Por qu? Aparentemente el compilador comienza leyendo la funcin main() y de repente encuentra algo que desconoce. No va ms all y nos muestra este aviso. Para satisfacer al compilador, simplemente debemos aadir una declaracin de funcin antes de la lnea con el main() [11.1]. No tiene complicacin, ya que es la misma lnea que en [10.12] excepto que termina con punto y coma (;). Ahora el compilador no se llevar una sorpresa cuando se encuentre la llamada a esa funcin.
//[11] float calculaAreaDelCirculo(float radio); // [11.1] declaracin de la funcin int main() { // Aqu va el cdigo de la funcin main... }

Nota: no se muestra aqu el resto del programa (ver [10]). En seguida compilaremos el programa en la realidad. Pero antes un par de comentarios. Cuando escribas programas es importante que intentes tener en mente la posibilidad de reutilizar tu cdigo en un futuro. Nuestro programa podra tener una funcin calculaAreaDelRectangulo() tal como la que se muestra a continuacin [12], que podra llamarse desde la funcin main(). Esto sera til incluso aunque slo se llamase a esa funcin una vez. La funcin main() sera ms fcil de leer. Si tuviramos que depurar el cdigo sera ms fcil encontrar el error analizando cada funcin que siguiendo una larga secuencia de instrucciones.
//[12] float calculaAreaDelRectangulo(float largo, float ancho) { return (largo * ancho); //[12.3] } // [12.1]

Como puedes ver, en un caso simple como este, es posible agrupar en una sola instruccin el clculo y la devolucin del resultado [12.3]. En [10.14] us la variable area simplemente para mostrar cmo declarar una variable dentro de una funcin. Aunque las funciones que definimos en este captulo son bastante sencillas, es importante darse cuenta de que se puede modificar el contenido de una funcin sin que ello afecte al
03: Funciones Pgina 5 de 6

Become an Xcoder Espaol v1.15

cdigo que la llama. Lo que no debe cambiarse es la declaracin de la funcin (es decir, su primera lnea). Por ejemplo, podemos cambiar el nombre de las variables internas de la funcin y seguir trabajando (y esto no influir en el resto del programa). Alguien podra escribir la funcin y t podras utilizarla sin conocer su interior. Todo lo que necesitas es saber cmo usarla. Ello implica conocer:
el nombre de la funcin el nmero, orden y tipo de cada argumento Lo que devuelve la funcin y el tipo del resultado

En el ejemplo [12], esas respuestas son, respectivamente:


calculaAreaDelRectangulo Dos argumentos, ambos de tipo float, siendo el primero el alto y el segundo el

ancho.
La funcin devuelve la superficie, y el resultado es de tipo float (como podemos

deducir de la primera palabra de la lnea [12.1]).

Variables protegidas
El cdigo de cada funcin est protegido del programa principal y de cualquier otra funcin. Esto significa que el valor de una variable interna de una funcin por defecto no puede ser modificado por ninguna otra variable de ninguna otra funcin, incluso aunque tuvieran el mismo nombre. Esta es una caracterstica esencial de Objective-C. En el captulo 5 volveremos a discutir este comportamiento. Pero antes vamos a arrancar Xcode y ejecutar el programa anterior [10].

03: Funciones

Pgina 6 de 6

Become an Xcoder Espaol v1.15

04: Salida en pantalla


Introduccin
Hemos hecho grandes progresos con nuestro programa, pero an no hemos visto como mostrar los resultados de nuestros clculos. El lenguaje Objective-C por si mismo no sabe como hacerlo, pero por suerte podemos utilizar funciones que han escrito otros ya. Hay varias opciones para mostrar resultados por pantalla. En este libro usaremos una funcin incluida en el entorno Cocoa de Apple: la funcin NSLog(). Esto es estupendo, porque no tenemos que preocuparnos (ni tenemos que programar nada al respecto) para obtener nuestros resultados en la pantalla. As que dnde muestra los datos NSLog()? En Xcode existe la Consola para visualizar los mensajes de log. Para abrir la Consola, debemos seleccionar [Console] desde el men [Run] (Cmd-Shift-R). Una vez que construyamos y ejecutemos nuestra aplicacin, todos los mensajes aparecern por ah. La funcin NSLog() se dise para mostrar mensajes de error, no para los resultados de una aplicacin. De todas formas es tan fcil de usar que la hemos adoptado en este libro para visualizar nuestros resultados. Una vez que conozcas Cocoa en profundidad descubrirs tcnicas ms sofisticadas para hacerlo.

Uso de NSLog
Veamos como usar la funcin NSLog() con el siguiente cdigo:
//[1] int main() { NSLog(@"Julia es mi actriz favorita."); return 0; }

Al ejecutarlo, se producir la aparicin del texto "Julia es mi actriz favorita" en la Consola. El texto entre @" y " (lo que est entre las comillas dobles) es lo que se llama "cadena de caracteres", "cadena de texto" o simplemente "cadena" (en ingls "string"). Adems de ese texto, la funcin NSLog() muestra informacin adicional, como la fecha actual y el nombre de la aplicacin. Por ejemplo, la salida completa del programa [1] en mi sistema es:
2010-03-12 22:12:38.052 prueba1[5006:a0f] Julia es mi actriz favorita.

Una cadena puede tener una longitud de cero o ms caracteres. Nota: en los siguientes ejemplos slo se muestran las sentencias interesantes de la funcin
main()

04: Salida en pantalla

Pgina 1 de 5

Become an Xcoder Espaol v1.15

//[2] NSLog(@""); //[2.1] NSLog(@" "); //[2.2]

La sentencia [2.1] contiene 0 caracteres y la llamamos cadena vaca (tiene una longitud 0). La sentencia [2.2] no es una cadena vaca aunque lo parezca. Contiene un espacio entre las comillas as que su longitud es 1. Hay algunas secuencias de caracteres que tienen un significado especial dentro de las cadenas. Se les llama "secuencias de escape". Por ejemplo para hacer que la ltima palabra de nuestra cadena empiece en una lnea nueva, debemos incluir un cdigo especial en la sentencia [3.1]. El cdigo es \n, que significa "carcter de nueva lnea".
//[3] NSLog(@"Julia es mi actriz \nfavorita.");

Ahora la salida tiene un aspecto como este (slo se muestra el contenido relevante):
Julia es mi actriz favorita.

La contrabarra (\) en [3.1] se llama carcter de escape, ya que indica a la funcin NSLog que el siguiente carcter no debe ser impreso directamente en pantalla sino que tiene un significado especial: en este caso la "n" significa "salta a la siguiente lnea". En el caso (no muy habitual) de que quisieras mostrar un contrabarra en pantalla, podra parecer que tienes un problema. Si el carcter tras la contrabarra tiene un significado especial, cmo ser posible imprimir una contrabarra?. Pues simplemente poniendo dos contrabarras juntas. Esto indicar a la funcin NSLog que debe imprimir la segunda contrabarra. Aqu tenemos un ejemplo:
//[4] NSLog(@"Julia es mi actriz favorita.\\n");

La sentencia [4.1] producir, tras la ejecucin, la siguiente salida:


Julia es mi actriz favorita.\n

Mostrar variables
Hasta ahora slo hemos mostrado cadenas estticas. Imprimamos ahora el resultado de un clculo.
//[5] int x, numeroAMostrar; x = 1; numeroAMostrar = 5 + x; NSLog(@"El valor del entero es %d.", numeroAMostrar);

04: Salida en pantalla

Pgina 2 de 5

Become an Xcoder Espaol v1.15

Fjate que, entre los parntesis, tenemos una cadena, una coma y el nombre de una variable. La cadena contiene algo curioso: %d. Al igual que la contrabarra, el carcter de porcentaje (%) tiene un sentido especial. Si va seguido de una d (abreviatura para indicar nmero entero en sistema decimal), hace que en esa posicin se inserte el valor que va a continuacin de la coma, en este caso el contenido de la variable numeroAMostrar. Al ejecutar el ejemplo [5] el resultado ser:
El valor del entero es 6.

Para mostrar un nmero con decimales (en ingls se llama tipo "float"), usaremos %f en lugar de %d.
//[6] float x, numeroAMostrar; x = 12345.09876; numeroAMostrar = x/3.1416; NSLog(@"El valor del nmero con decimales es %f.", numeroAMostrar);

Ms tarde, cuando aprendas a hacer repeticiones de clculos, podras queres realizar una tabla de valores. Imagina una tabla de conversin de grados Fahrenheit a Celsius. Si quieres que los datos mostrados tengan buena apariencia, necesitars que los datos en cada una de las dos columnas tengan un ancho fijo. Puedes especificar ese ancho introduciendo un nmero entero entre % y f (o entre % y d segn el tipo de variable). An as, si el ancho que especificas es menor que el ancho del nmero, prevalecer el ancho del nmero.
//[8] int x = 123456; NSLog(@"%2d", x); NSLog(@"%4d", x); NSLog(@"%6d", x); NSLog(@"%8d", x);

La ejecucin del ejemplo [8] producir la siguiente salida:


123456 123456 123456 123456

En las dos primeras sentencias [8.2, 8.3] solicitamos demasiado poco espacio para que el nmero sea mostrado completamente, pero se toma el espacio igualmente. Slo en la sentencia [8.5] se especifica un ancho mayor que el del valor, y es donde apreciamos los espacios adicionales que se han requerido para mostrar el nmero. Tambin es posible combinar la especificacin del ancho y el nmero de decimales con los que queremos que se muestre el dato.
//[9] float x=1234.5678; NSLog(@"Reserva espacio para 10, y muestra 2 dgitos significativos."); NSLog(@"%10.2f", x);

04: Salida en pantalla

Pgina 3 de 5

Become an Xcoder Espaol v1.15

Mostrar mltiples valores


Por supuesto es posible mostrar ms de un valor o cualquier combinacin de valores [10.3]. Lo que debes hacer es asegurarte de indicar correctamente el tipo de cada dato (int, float), usando %d y %f.
//[10] int x = 8; float pi = 3.1416; NSLog(@"El valor de x es %d, mientras que el valor de pi es %f.", x, pi);

Asignar los smbolos a los valores


Uno de los errores ms comunes entre los principiantes es especificar incorrectamente el tipo en funciones como NSLog y otras. Si tus resultados no son los esperados o el programa rompe sin una razn, revisa las sentencias en las que asignas los tipos de dato. Si es incorrecta la asignacin del primer dato, puede que el segundo tampoco sea mostrado correctamente. Un ejemplo:
//[10b] int x = 8; float pi = 3.1416; NSLog(@"El valor int es %f, mientras que el valor float es %f.", x, pi); // Lo correcto sera : NSLog(@"El valor int es %d, mientras que el valor float es %f.", x, pi);

produce la siguiente salida por consola:


El valor int es 3.141600, y el float es nan.

Vincular con la librera Foundation


Estamos a solamente una pregunta y una respuesta de ejecutar nuestro primer programa. Cmo hace nuestro programa para conocer la funcin NSLog()? Bien, realmente no la conoce, a menos que nosotros se lo digamos. Para hacerlo, tenemos que indicar al compilador que importe la librera en la que est implementada la funcin NSLog() (junto a otras muchas que iremos conociendo). La sentencia es la siguiente:
#import <Foundation/Foundation.h>

sta debe ser la primera sentencia en nuestro programa. Si juntamos todo lo que hemos aprendido en este captulo obtendremos el siguiente cdigo, que haremos funcionar en el siguiente captulo.
//[11] #import <Foundation/Foundation.h> float calculaAreaDelCirculo(float radio);

04: Salida en pantalla

Pgina 4 de 5

Become an Xcoder Espaol v1.15

float calculaAreaDelRectangulo(float ancho, float alto); int main() { float anchoDelDibujo, altoDelDibujo, areaDelDibujo, radioDelCirculo, areaDelCirculo; anchoDelDibujo = 8.0; altoDelDibujo = 4.5; radioDelCirculo = 5.0; areaDelDibujo = calculaAreaDelRectangulo(anchoDelDibujo, altoDelDibujo); areaDelCirculo = calculaAreaDelCirculo(radioDelCirculo); NSLog(@"Area del crculo: %10.2f.", areaDelCirculo); NSLog(@"Area del cuadrado: %f.", areaDelDibujo); return 0; } float calculaAreaDelCirculo(float radio) // primera funcin personalizada { float area; area = 3.1416 * radio * radio; return area; } float calculaAreaDelRectangulo(float ancho, float alto) // segunda funcin personalizada { return ancho* alto; }

04: Salida en pantalla

Pgina 5 de 5

Become an Xcoder Espaol v1.15

05: Compilacin y ejecucin de un Programa


Introduccin
El cdigo que hemos escrito hasta ahora no es ms que texto relativamente sencillo de leer para nosotros. No es que sea prosa precisamente, pero es an peor para nuestro Mac. No puede hacer nada con l! Se necesita un programa especial, llamado compilador, para convertir este texto en un conjunto de instrucciones que el Mac pueda entender y ejecutar. El compilador es parte de Xcode, el entorno de programacin gratuito de Apple. Deberas haber instalado Xcode desde el disco que viene con la copia de Mac OS X. En cualquier caso, verifica que tienes la ltima versin, que puedes descargar en http://developer.apple.com/ (se requiere registro gratuito).

Crear un proyecto
Arranca Xcode, que encontrars en /Developer/Applications. La primera vez te har responder algunas preguntas. Acepta las sugerencias que l haga, en principio son adecuadas y adems podrs modificarlas ms adelante en el men Preferencias. Para empezar realmente, selecciona New Project en el men File. Aparece una ventana de dilogo con los tipos de proyecto disponibles. El aspecto puede variar ligeramente segn la versin de Xcode.

05: Compilacin y ejecucin de un Programa

Pgina 1 de 10

Become an Xcoder Espaol v1.15

El asistente de Xcode te permite crear nuevos proyectos. En este momento queremos crear un programa simple en Objective-C, sin GUI (Interfaz grfica de usuario), as que dentro de Command Line Tool selecciona Type Foundation.

05: Compilacin y ejecucin de un Programa

Pgina 2 de 10

Become an Xcoder Espaol v1.15

Introduce un nombre para tu aplicacin, como "justatry". Selecciona el lugar en el que quieres guardar tu proyecto y pulsa Finish. El proyecto que estamos creando va a poder ejecutarse desde el Terminal (/Aplicaciones/Utilidades/Terminal). Si quieres evitarte molestias, asegrate de que el nombre del proyecto consta de una sola palabra (sin espacios). Tambin es costumbre que los nombres de programas que se ejecutan en terminal comiencen por minscula. Por el contrario, los nombres de programas con interfaz grfica suelen comenzar por mayscula.

Explorando Xcode
A continuacin se muestra una ventana que t como programador vers con frecuencia. Tiene dos marcos principales a derecha e izquierda. El de la izquierda es "Groups & Files", desde el que accedemos a todos los elementos de los que consta nuestro proyecto. En este momento no hay demasiados, pero cuando creemos programas con interfaz grfica (GUI) y multiidioma, aqu veremos todos los ficheros relacionados con la GUI y con los diferentes idiomas. Los ficheros se agrupan en carpetas, pero no busques esas carpetas en tu Mac con el Finder ya que son virtuales; aparecen aqu para organizar nuestro trabajo. En el marco "Groups & Files" abre el grupo justatry (pulsando el tringulo gris que est a la izquierda de su nombre) y dentro de ste abre el grupo Source. Dentro encontrars un fichero llamado justatry.m [1]. Recuerdas que todo programa debe contener una funcin llamada main()? Bien, este es el fichero que contiene la funcin main(). Ms tarde en este captulo vamos a modificarla para incluir el cdigo de nuestro programa. Si abres justatry.m te llevars una sorpresa: Apple ha creado ya por ti la funcin main().

05: Compilacin y ejecucin de un Programa

Pgina 3 de 10

Become an Xcoder Espaol v1.15

Xcode mostrando la funcin main().


//[1] #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) //[1.2] { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //[1.4] // insert code here... NSLog(@"Hello, World!"); [pool drain]; //[1.7] return 0; }

Echa un vistazo al cdigo y busca elementos que puedas reconocer. Vers:


La sentencia import necesaria para poder utilizar funciones como NSLog(). La funcin main(). Las llaves entre las que debemos encerrar el cdigo de nuestro programa. Un comentario, que nos invita a escribir cdigo en esa posicin. Una instruccin con NSLog(), para mostrar una cadena de texto en pantalla. Una sentencia return 0;.

Pero tambin hay algunas cosas que no reconocemos:


Los argumentos que se le pasan a la funcin main(). [1.2] Una lnea que empieza por NSAutoreleasePool [1.4] Otra lnea que contiene las palabras pool y drain [1.7].

05: Compilacin y ejecucin de un Programa

Pgina 4 de 10

Become an Xcoder Espaol v1.15

Personalmente no me gusta que los autores de libros me muestren a mi, como lector, cdigo lleno de elementos desconocidos y me prometan que ms adelante lo ver todo claro. Por eso he preferido explicar en captulos anteriores lo que son las funciones, para que no te enfrentes ahora a demasiados conceptos nuevos. As que ahora ya sabes que las funciones son una forma de organizar el cdigo, que todos los programas tienen una funcin main() y cual es el aspecto de las funciones. An as, debo admitir que por ahora no puedo explicar completamente todo lo que ves en el ejemplo [1]. Siento tener que pedirte que ignores lo que ves en [1.2, 1.4 y 1.7]. Antes debes familiarizarte con otros elementos de Objective-C. La buena noticia es que ya has pasado dos captulos complicados y los tres siguientes son bastante llevaderos, antes de que tengamos que tratar de nuevo con cuestiones complejas. Si realmente no aguantas sin una explicacin, aqu va un resumen. Los argumentos que se pasan a la funcin main() son necesarios para poder ejecutar el programa en el Terminal. Los programas necesitan memoria para funcionar y deben dejarla a disposicin del resto cuando ya no es necesaria. Al comienzo del programa, en [1.4], solicitamos la memoria y en [1.7] la liberamos justo antes de que el programa termine.

Build and run (Compilar y ejecutar)


Ejecutemos el programa que ha preparado Apple [1]. En primer lugar necesitamos abrir la ventana Console (Consola), que est en el men Run, para ver los resultados. Despus pulsaremos el icono del martillo con el texto "Build and Run" para que se compile y ejecute el programa.

El botn Build and Run. El programa se ejecuta y se muestran sus resultados en la ventana Console, junto con informacin adicional. La ltima lnea notifica que el programa ha finalizado con un valor de estado 0. Ese es el valor que ha devuelto la funcin main(), tal como vimos en el captulo 3 [7.9]. Por tanto, nuestro programa ha llegado hasta la ltima lnea sin haber terminado prematuramente. No est mal para empezar!

Control de errores
Vayamos al ejemplo [1] y veamos qu sucede cuando hay un error en el programa. Por ejemplo, he reemplazado la sentencia NSLog() con otra, pero he olvidado poner el carcter punto y coma al final.

05: Compilacin y ejecucin de un Programa

Pgina 5 de 10

Become an Xcoder Espaol v1.15

//[2] #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // insert code here... NSLog(@"Julia es mi actriz favorita") //Oh, he olvidado el punto y coma! [pool drain]; //[2.9] return 0; }

Para compilar la aplicacin pulsa el icono Build en la barra de herramientas (si no lo tienes, pulsa la opcin Build dentro del men Build). Aparecer un indicador rojo antes de la lnea [2.9].

Xcode seala un error de compilacin. Segn la versin de Xcode podrs ver una descripcin del error a la derecha de la lnea o tendrs que pulsar en el marcador rojo para que se despliegue la descripcin del error. Lo primero que hace el compilador es analizar el cdigo, recorriendo cada lnea para comprobar si puede entender su contenido. Nosotros, para ayudarle, tenemos que dejarle algunas pistas. Por ejemplo, antes de cada sentencia import hay que poner una almohadilla (#). Tambin, para indicar el final de una instruccin, hay que poner un punto y coma. En el momento en que llega a la lnea [2.9] es cuando el compilador se da cuenta de que algo va mal, pero no sabe que el problema no est en esta lnea sino en la anterior, en la que falta el punto y coma. La leccin que debemos aprender es que la informacin que nos da el compilador no siempre es una descripcin precisa del error, e incluso puede que no sea exacta la posicin del error (aunque seguro que est muy cerca). Arregla el programa aadiendo el punto y coma y ejectalo de nuevo para asegurarte de que funciona.

Nuestra primera aplicacin

05: Compilacin y ejecucin de un Programa

Pgina 6 de 10

Become an Xcoder Espaol v1.15

Ahora vamos a coger el programa que preparamos en el captulo anterior y lo mezclamos con el cdigo que ha escrito ya Apple. Debera quedar algo as [3]:
//[3] #import <Foundation/Foundation.h> float calculaAreaDelCirculo(float radio); //[3.3] float calculaAreaDelRectangulo(float ancho, float alto); //[3.4] int main(int argc, const char * argv[]) // [3.6] { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; float anchoDelDibujo, altoDelDibujo, areaDelDibujo, radioDelCirculo, areaDelCirculo; anchoDelDibujo = 8.0; altoDelDibujo = 4.5; radioDelCirculo = 5.0; areaDelDibujo = calculaAreaDelRectangulo(anchoDelDibujo, altoDelDibujo); areaDelCirculo = calculaAreaDelCirculo(radioDelCirculo); NSLog(@"Area del crculo: %10.2f.", areaDelCirculo); NSLog(@"Area del cuadrado: %f.", areaDelDibujo); [pool drain]; return 0; } float calculaAreaDelCirculo(float radio) // [3.22] { float area; area = 3.1416 * radio * radio; return area; } float calculaAreaDelRectangulo(float ancho, float alto) // [3.29] { return ancho * alto; }

Toma tu tiempo para asegurarte de que entiendes la estructura del programa. Tenemos las declaraciones de nuestras propias funciones en [3.3 y 3.4] antes de la funcin main() en la lnea [3.6]. Nuestras funciones estn implementadas fuera de las llaves de la funcin main() y hemos puesto el cuerpo de nuestra funcin main() en el lugar que nos haba indicado Apple. Cuando ejecutemos el programa, obtendremos la siguiente salida:
Running 2010-03-14 00:54:24.494 justatry[8613:a0f] Area del crculo: 78.54. 2010-03-14 00:54:24.496 justatry[8613:a0f] Area del cuadrado: 36.000000. Debugger stopped. Program exited with status value:0.

Depurando
Segn se van complicando los programas, se hacen ms difciles de depurar. Xcode nos da la opcin de saber qu sucede dentro del programa mientras est corriendo. Para ello haremos click con el ratn en el margen gris que est a la izquierda del cdigo (en la zona en la que aparecen los nmeros de lnea), en la lnea en la que queremos que el programa nos muestre
05: Compilacin y ejecucin de un Programa Pgina 7 de 10

Become an Xcoder Espaol v1.15

los valores de las variables. En ese punto Xcode insertar un "breakpoint" (punto de ruptura), representado por una flecha azul.

Colocando breakpoints (puntos de ruptura) en nuestro cdigo. En este caso podemos ver uno en la lnea 15 En la siguiente seccin veremos cmo el Debugger nos muestra el estado de las variables al llegar al punto de ruptura. Pero ten en cuenta que sern los valores de "antes" de que se ejecute la lnea en la que hemos parado, as que puede que te convenga poner el breakpoint "despus" de la lnea que te interesa. En cuanto insertes el primer breakpoint vers que el icono con el martillo cambia ligeramente y en el texto se lee "Build and Debug" (Compilar y depurar). En versiones anteriores tienes que mantener pulsado el ratn en el icono del martillo hasta que aparezca un men.

El botn de compilar y depurar. Para seguir lo que est sucediendo necesitas abrir dos ventanas: Console y Debugger, que estn en el men Run. La Consola mostrar un texto parecido a este:
[Session started at 2009-06-03 15:48:02 +1000.] Loading program into debugger 05: Compilacin y ejecucin de un Programa Pgina 8 de 10

Become an Xcoder Espaol v1.15

GNU gdb 6.3.50-20050815 (Apple version gdb-956) (Wed Apr 30 05:08:47 UTC 2008) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-apple-darwin".tty /dev/ttys000 Program loaded. sharedlibrary apply-load-rules all run [Switching to process 86746 local thread 0x2d03] Running

Esto quiere indica que nuestra aplicacin ha sido compilada y lanzada, y que se ha cargado el Debugger (depurador). La ventana del Debugger tendr un aspecto parecido a este:

05: Compilacin y ejecucin de un Programa

Pgina 9 de 10

Become an Xcoder Espaol v1.15

El Depurador de Xcode te permite ejecutar el programa paso a paso y consultar el valor de las variables. El programa se ejecutar hasta que alcance el primer breakpoint. Si compruebas el panel superior derecho puedes leer el valor de las variables. Se muestran en color rojo los valores que han cambiado desde el anterior breakpoint. Para continuar la ejecucin pulsa el botn Continue. Los botones Step Over y Step Into sirven para ejecutar el programa instruccin a instruccin. Prueba el Debugger durante un rato para familiarizarte con l, es una herramienta poderosa.

Conclusin
Ya tenemos todo lo necesario para escribir, depurar y ejecutar programas sencillos para Mac OS X. Si no deseas realizar programas con interfaz grfico, todo lo que te falta es ir conociendo en profundidad Objective-C para desarrollar programas no grficos ms sofisticados. En los siguientes captulos vamos a hacer exactamente eso. Y despus, nos sumergiremos en aplicaciones con GUI (Interfaz Grfico de Usuario). Sigue leyendo!

05: Compilacin y ejecucin de un Programa

Pgina 10 de 10

Become an Xcoder Espaol v1.15

06: Sentencias condicionales


if()
A veces vas a querer que tu cdigo realice una serie de acciones slo si se dan unas determinadas condiciones. Veamos un ejemplo sencillo [1.2].
//[1] // 'edad' es una variable de tipo int en la que guardamos la edad del usuario if (edad > 30) // [1.2] El smbolo > significa "mayor que" { NSLog(@"La edad es mayor que 30."); //[1.4] } NSLog(@"Terminado."); //[1.6]

La lnea [1.2] contiene una instruccin if(), tambin conocida como instruccin condicional. Vers que a continuacin tiene unas llaves que encierran el cdigo que queremos que se ejecute cuando sea verdadera la condicin que se indica entre parntesis. En este caso, si la condicin edad > 30 es cierta, entonces se mostrar la cadena que vemos en [1.4]. En cualquier caso, sea cierta o no esa condicin, siempre se va a mostrar la cadena en [1.6], ya que est fuera de las llaves de la instruccin if().

if() else
Tambin podemos indicar una serie de instrucciones que queremos que se realicen cuando no sea cierta la condicin, usando la sentencia ifelse [2].
//[2] // 'edad' es una variable entera en la que guardamos la edad del usuario if (edad > 30) //[2.2] { NSLog(@"La edad es mayor que 30."); //[2.4] } else { NSLog(@"La edad es inferior a 30."); //[2.7] } NSLog(@"Terminado.");

La cadena de la sentencia [2.7] slo se mostrar cuando no sea cierta la condicin edad >
30.

Comparaciones
Adems del "mayor que" que hemos visto en [2.2], tenemos a nuestra disposicin otros operadores para comparar nmeros.
== igual a

06: Sentencias condicionales

Pgina 1 de 3

Become an Xcoder Espaol v1.15

> < >= <= !=

mayor que menor que mayor o igual que menor o igual que distinto de

Presta especial atencin a que el operador para comparar la igualdad tiene dos signos de igual y es muy fcil olvidarse esto y utilizar un solo signo de igualdad. Como ya hemos visto, un solo signo igual lo que hace es asignar un valor a una variable en lugar de compararla con ese valor. Este es un error muy frecuente, as que repite conmigo en alto: No voy a olvidar escribir dos signos de igualdad cuando vaya a comparar la igualdad! Los operadores de comparacin son bastante tiles cuando quieres repetir una serie de instrucciones varias veces. Esto ser un tema para el siguiente captulo. Antes discutiremos otros aspectos de las sentencias condicionales.

Ejercicio
Echemos un vistazo de cerca al hecho de la comparacin. Una operacin de comparacin puede tener solamente dos resultados: que sea verdadera o que sea falsa. En Objective-C, verdadero y falso se representan, respectivamente, por 1 y 0. Incluso hay un tipo de dato especial, llamado BOOL, que puedes utilizar para representar esos valores. Para indicar el valor "verdadero", puedes emplear tanto 1 como YES. Para indicar un valor "falso", puedes emplear tanto 0 como NO.
//[3] int x = 3; BOOL y; y = (x == 4); valor 0.

// despus de esta instruccin, la variable 'y' tendr el

Es posible comprobar ms de una condicin. Cuando deban ser ciertas todas las condiciones, usaremos el operador representado por dos ampersands: &&. Si basta con que sea cierta una de las condiciones, usaremos el operador representado por dos barras verticales: ||.
//[4] // Condiciones con el operador lgico Y if ( (edad > 18) && (edad < 65) ) // Si es mayor de 18 y es menor de 65 { NSLog(@"Probablemente necesite trabajar para vivir."); } // // Condiciones con el operador lgico O if ( (kilometrosRecorridos > 100000) || (antiguedad > 4) ) { // Si ha recorrido ms de 100000 km o tiene ms de 4 aos NSLog(@"Debe revisar el coche."); }

06: Sentencias condicionales

Pgina 2 de 3

Become an Xcoder Espaol v1.15

Tambin es posible anidar sentencias condicionales. Es tan sencillo como poner una sentencia condicional dentro de las llaves de otra sentencia condicional. Primero se evala la condicin exterior y, slo si es cierta, se evaluar la condicin en su interior:
//[5] if (edad >= 18) // Si es mayor o igual que 18 { if (edad < 65) // Si es menor que 65 { NSLog(@"Probablemente necesite trabajar para vivir."); } }

06: Sentencias condicionales

Pgina 3 de 3

Become an Xcoder Espaol v1.15

07: Ejecucin de bucles


Introduccin
En todo el cdigo que hemos visto hasta ahora, cada instruccin se ejecutaba solamente una vez. Siempre podramos volver a ejecutar funciones llamndolas repetidamente [1].
//[1] NSLog(@"Julia es mi actriz favorita."); NSLog(@"Julia es mi actriz favorita."); NSLog(@"Julia es mi actriz favorita.");

Pero eso requiere repetir la llamada cada vez. Como todos los lenguajes de programacin, Objective-C ofrece varias formas de ejecutar un bucle de instrucciones.

for()
Si sabes el nmero de veces que quieres repetir la instruccin (o secuencia de instrucciones), puedes especificarlo en una sentencia for() tal como la que vemos en el ejemplo [2]. El nmero de repeticiones debe ser un nmero entero, ya que no se puede repetir una operacin, por ejemplo, 2,7 veces.
//[2] int x; for (x = 1; x <= 10; x++) //[2.2] { NSLog(@"Julia es mi actriz favorita."); } NSLog(@"El valor de x es %d", x); //[2.6]

//[2.4]

En el ejemplo [2], la cadena en [2.4] se va a imprimir 10 veces. En una sentencia for() vamos a encontrar entre los parntesis tres secciones separadas por punto y coma (;). La secuencia es la siguiente:
[1] Se ejecuta la seccin 1 del for [2] Se evala la seccin 2 del for Si es cierta, entonces, se ejecutan las instrucciones que hay dentro de las llaves se ejecuta la seccin 3 del for se salta al paso [2] Si no es cierta: se sale del bucle for

Vamos a explicar la secuencia con el ejemplo [2]. Primero se asigna a x el valor 1. Despus se evala la condicin, que en este caso es x <= 10. La condicin se cumple, ya que la primera vez x es igual a 1, por lo tanto se ejecutarn los comandos en el interior de las llaves del for(). Como la condicin ha sido cierta, se ejecuta la seccin 3, que en este caso incrementa el valor de x en 1 (eso es lo que significa x++). As que ahora x es igual a 2 y se
07: Ejecucin de bucles Pgina 1 de 3

Become an Xcoder Espaol v1.15

vuelve a evaluar la expresin x <= 10. Como sigue siendo cierta, se vuelven a ejecutar las instrucciones entre llaves y se vuelve a incrementar en 1 el valor de x. As seguir sucediendo hasta el momento en que x sea igual a 11. En este momento la condicin no se cumplir y saldremos del bucle for(). Hemos puesto la lnea [2.6] para probar que cuando se llega ah, x es igual a 11. Habr ocasiones en que necesitemos otros incrementos distintos de x++. En el ejemplo [3] vamos a convertir de grados Fahrenheit a Celsius.
//[3] float celsius, tempEnFahrenheit; for (tempEnFahrenheit = 0; tempEnFahrenheit <= 200; tempEnFahrenheit = tempEnFahrenheit + 20) { celsius = (tempEnFahrenheit - 32.0) * 5.0 / 9.0; NSLog(@"%10.2f -> %10.2f", tempEnFahrenheit, celsius); }

La salida del programa ser:


0.00 -> -17.78 20.00 -> -6.67 40.00 -> 4.44 60.00 -> 15.56 80.00 -> 26.67 100.00 -> 37.78 120.00 -> 48.89 140.00 -> 60.00 160.00 -> 71.11 180.00 -> 82.22 200.00 -> 93.33

while()
En Objective-C encontramos tambin otras formas de repetir una serie de instrucciones:
while () { }

y
do {} while ()

El funcionamiento es bsicamente idntico al bucle for(): empieza evaluando una condicin y en el momento en que esa condicin sea falsa deja de ejecutar las instrucciones entre llaves.
//[4] int contador = 1; while (contador <= 10) { NSLog(@"Julia es mi actriz favorita.\n"); contador = contador + 1;

07: Ejecucin de bucles

Pgina 2 de 3

Become an Xcoder Espaol v1.15

} NSLog(@"El valor del contador es %d", contador);

El valor de contador al salir del bucle es 11. La instruction do {} while () es ligeramente diferente, ya que las instrucciones entre llaves se va a ejecutar siempre al menos una vez. Eso es debido a que primero se ejecutan las instrucciones entre llaves y despus de evala la condicin entre parntesis.
//[5] int contador = 1; do { NSLog(@"Julia es mi actriz favorita.\n"); contador = contador + 1; } while (contador <= 10); NSLog(@"El valor del contador es %d", contador);

Podremos comprobar que el valor de contador al salir del bucle es 11. Hemos aumentado nuestro nivel como programadores y es el momento de abordar un objetivo ms alto. En el siguiente captulo construiremos nuestro primer programa con Interfaz Grfico de Usuario (GUI).

07: Ejecucin de bucles

Pgina 3 de 3

Become an Xcoder Espaol v1.15

08: Programas con entorno grfico


Introduccin
Al haber incrementado nuestro conocimiento de Objective-C, estamos ya preparados para crear un programa con Interfaz Grfica de Usuario (GUI). En este punto debo confesar algo. Objective-C es una extensin de otro lenguaje de programacin llamado C. Hasta ahora, prcticamente todo lo que hemos visto es simplemente lenguaje C. As que, dnde est la diferencia entre Objective-C y C?, pues precisamente en la parte "Objective". Objective-C trata con unos elementos abstractos llamados objetos. Hasta ahora hemos tratado principalmente con nmeros, hemos visto como Objective-C crea nmeros en memoria y podemos manipularlos con operadores y funciones matemticas. Esto nos viene bien cuando nuestra aplicacin trabaja con nmeros (por ejemplo, una calculadora). Pero qu ocurre si nuestra aplicacin es, digamos, un reproductor de msica que usar canciones, listas de reproduccin, artistas, etc.? O si es un sistema de control de trfico areo que tratar con aviones, vuelos, aeropuertos, etc.? Sera bueno poder manipular tales elementos con la misma facilidad con la que podemos manipular nmeros. Y aqu acuden los objetos. Con Objective-C puedes definir las clases de objetos con los que quieres tratar y despus escribir aplicaciones para manipularlos.

Objetos en accin
Como ejemplo, veamos cmo se manejan las ventanas en un programa escrito en ObjectiveC, tal como Safari. Ve a una ventana abierta de Safari en tu Mac; en la parte superior izquierda hay tres botones. El botn rojo es para cerrar. Qu ocurre cuando haces click en ese botn? Se enva un mensaje a esa ventana y en respuesta a dicho mensaje la ventana ejecuta cdigo para cerrarse.

08: Programas con entorno grfico

Pgina 1 de 21

Become an Xcoder Espaol v1.15

Se enva un mensaje de cierre a la ventana La ventana es un objeto. Puedes, por ejemplo, desplazarla. Los tres botones son objetos. Puedes pulsarlos. Estos objetos tienen una representacin visual en la pantalla, pero no es as con todos; por ejemplo el objeto que representa la conexin entre Safari y un sitio web no tiene una representacin visual.

Un objeto (por ej. la ventana) puede contener otros objetos (p.ej. los botones) Puedes tener tantas ventanas abiertas de Safari como quieras. Podras pensar que los programadores de Apple:

a. Han programado previamente todas las posibles ventanas, usando su poder mental para anticiparse a todas las ventanas que t podras querer abrir, o b. Hicieron una especie de plantilla y dejan que Safari cree cada ventana a partir de esa plantilla cuando haga falta.

Por supuesto, la respuesta correcta es la b. Crearon un cdigo, llamado clase, que define la ventana, incluyendo su aspecto y comportamiento. Cuando creas una ventana, realmente es la clase la que crea la ventana por ti. Esta clase representa el concepto de ventana y cualquier ventana concreta es realmente una instancia de ese concepto (de la misma manera que 76 es una instancia del concepto nmero). Puedes imaginarte la clase como los planos de una casa, incluyendo la descripcin de sus instalaciones, y objeto como cada una de las casas reales que se han construido a partir de ese proyecto.

08: Programas con entorno grfico

Pgina 2 de 21

Become an Xcoder Espaol v1.15

Variables de instancia
La ventana que has creado est colocada en una posicin determinada de la pantalla. Si minimizas la ventana en el Dock y la haces reaparecer, se coloca exactamente en donde estaba Cmo lo hace? La clase define variables para recordar la posicin y cada instancia de esa clase, es decir, cada objeto, contiene sus valores de posicin.

Mtodos
La clase tambin nos da acceso a una serie de acciones que puede realizar. Una de las acciones de la clase "ventana" es cerrarse. Cuando pulsas el botn para cerrar una ventana, el botn enva un mensaje de cierre a ese objeto de ventana. A esas acciones se les llama mtodos. Como vers, se parecen mucho al concepto de funciones que ya hemos visto, as que si nos has seguido hasta aqu no vas a tener problema en aprenderlo.

Objetos en memoria
Cuando la clase crea un objeto de ventana para ti, reserva memoria (RAM) para almacenar su posicin adems de mucha otra informacin. Sin embargo, no hace una copia del cdigo para cerrar la ventana; eso sera un desperdicio de memoria ya que el cdigo es el mismo para todos los objetos de la misma clase. El cdigo para cerrar la ventana necesita estar presente slo una vez, pero cada objeto de ventana ha de tener acceso a todo el cdigo de la clase a la que pertenece. Como ya vimos anteriormente, el cdigo que vamos a ver en este captulo contiene algunas lneas para reservar memoria y dejarla a disposicin del sistema al terminar. Pero an es pronto para hablar sobre ello, lo veremos ms adelante.

Ejercicio
Nuestra aplicacin
Vamos a crear una aplicacin con dos botones y un campo de texto. Si presionas un botn, aparecer un valor en el campo de texto. Si presionas el otro botn, se introducir otro valor en el campo de texto. Piensa en ello como una calculadora de dos botones que no puede hacer clculos. Por supuesto, cuando aprendas ms llegars a hacer una calculadora real, pero es mejor ir paso a paso.

08: Programas con entorno grfico

Pgina 3 de 21

Become an Xcoder Espaol v1.15

Un esquema de la aplicacin que queremos crear Cuando se pulse uno de los botones de la aplicacin, enviar un mensaje. El mensaje contiene el nombre del mtodo que se va a ejecutar. A dnde se enva el mensaje? En el caso de la ventana, el mensaje de cierre se enva a ese objeto ventana, que es una instancia de la clase ventana. Lo que necesitamos en nuestro caso es un objeto capaz de recibir mensajes de cada uno de los dos botones y que pueda indicar al campo de texto que muestre un valor.

Nuestra primera clase


As que primero debemos implementar nuestra propia clase y luego crear una instancia de ella. Ese objeto ser receptor de los mensajes de los botones (ver esquema ms abajo). Al igual que un objeto ventana nuestra instancia tambin es un objeto, pero no a diferencia de las ventanas, nuestro objeto no tiene una representacin visual; slo es algo dentro de la memoria de nuestro Mac. Cuando nuestra instancia recibe un mensaje enviado por uno de los dos botones se ejecuta el mtodo apropiado. Recordamos que el cdigo de ese mtodo est almacenado en la clase, no en la propia instancia. Durante la ejecucin, este mtodo modificar el texto del objeto campo de texto. Cmo sabr el mtodo de nuestra clase cmo asignar el texto de un campo de texto? Realmente no lo sabe. Pero el propio campo de texto s sabe como modificar su propio texto. As que enviaremos un mensaje al campo de texto pidindole que haga el trabajo. Qu contenido ha de tener ese mensaje? Por supuesto hay que indicar el objeto receptor del mensaje, que en este caso es el campo de texto. Tambin necesitamos indicar qu es lo que queremos que haga el receptor, es decir, en este caso hay que dar el nombre del mtodo que tiene el campo de texto para mostrar un texto (esto implica conocer los mtodos que pone a nuestra disposicin un campo de texto, ya hablaremos sobre ello). En este caso, nuestro mensaje tambin debe contener el valor que queremos que muestre. A los datos que hay que aportar al mtodo (en este caso: el valor que queremos que muestre) se les llama argumentos.

08: Programas con entorno grfico

Pgina 4 de 21

Become an Xcoder Espaol v1.15

Un esquema del intercambio de mensajes entre objetos de nuestra aplicacin Este es el formato general para enviar mensajes en Objective-C, tanto sin argumentos [1.1], como con un argumento [1.2]:
//[1] [receptor mensaje]; // [1.1] [receptor mensajeQueRequiereUnArgumento:elArgumento]; // [1.2]

Como puedes ver en cada una de las sentencias, todo el contenido est encerrado entre corchetes, por supuesto con punto y coma al final. Dentro de los corchetes, primero aparece el objeto receptor del mensaje, seguido del nombre del mtodo que vamos a invocar separado por espacio. Si se requiere un argumento, ir a continuacin separado por dos puntos. [1.2].

Creacin del proyecto


Veamos como llevar esto a la prctica. Arranca Xcode para crear un nuevo proyecto. Selecciona Cocoa Application. Dale un nombre a tu proyecto, como "Mi primera apli" (por convencin, el nombre de una aplicacin con GUI debera comenzar por mayscula). En la parte izquierda, en la seccin Groups & Files, abre la carpeta Resources y haz doble-click en MainMenu.xib.

08: Programas con entorno grfico

Pgina 5 de 21

Become an Xcoder Espaol v1.15

Haz doble-click en el fichero MainMenu.xib de Xcode Si ests usando una versin anterior a Xcode 3, vers que el nombre del fichero ser nib en lugar de xib. No tiene importancia ya que los ficheros son iguales a todos los efectos.

Creacin de la GUI (Interfaz grfica de usuario)


Al abrir el fichero MainMenu.xib se abrir otro programa, Interface Builder (traducido como Generador de Interfaces). Ya que van a aparecer muchas ventanas, podra interesarte seleccionar la opcin Hide Others (Ocultar el resto de ventanas) del men Interface Builder. Una de las ventanas tiene en el ttulo el nombre que has dado a tu proyecto y no tiene contenido: es la que vern los usuarios de tu aplicacin. Si la ves demasiado grande puedes redimensionarla. Vers tambin otra ventana que se llama "Library": es una especie de repositorio de todos los tipos de objetos que puedes tener en tu GUI. Selecciona el elemento "Objects" en la parte superior de la ventana y desplzate por la lista hasta encontrar los botones (Push Button). Arrastra dos botones a tu ventana de aplicacin, uno cada vez. Sigue desplazndote ms abajo en la lista de objetos hasta encontrar uno con el texto "Label" y arrastra uno de estos objetos a tu ventana. Podemos modificar el modo de presentacin de los objetos en la ventana "Library" pulsando el pequeo botn con una rueda dentada que hay en la parte inferior de la ventana: desde ver slo los iconos, hasta que se incluya la descripcin al lado de cada objeto.

08: Programas con entorno grfico

Pgina 6 de 21

Become an Xcoder Espaol v1.15

Arrastrando objetos de la ventana "Library" hasta la ventana de tu aplicacin. Internamente, al arrastrar los objetos de la ventana "Library" a la ventana de aplicacin, se crean esos objetos y se colocan en la ventana. Fjate que al hacer click sobre los objetos de la ventana "Library", en la parte inferior aparece un nombre descriptivo, como "Push Button" y debajo otro nombre como NSButton. Este ltimo es el nombre de clase que proporciona Apple. Ms tarde en este captulo veremos como encontrar los mtodos que nos ofrecen estas clases, los cuales nos harn falta para realizar las acciones necesarias en nuestro programa. No olvides guardar el fichero regularmente (File -> Save) para que Interface Builder y Xcode se mantengan sincronizados. Recoloca los objetos en tu ventana de aplicacin para que queden con buen aspecto: arrstralos y redimensinalos a tu gusto. Puedes cambiar el texto de los botones haciendo doble-click sobre l. Es conveniente que explores la paleta de objetos y practiques a aadir otros objetos a tu ventana.

08: Programas con entorno grfico

Pgina 7 de 21

Become an Xcoder Espaol v1.15

Conociendo Interface Builder


Para cambiar las propiedades de un objeto, seleccinalo y pulsa Cmd-Shift-I. Por ejemplo selecciona tu ventana de aplicacin, pulsando en la barra de ttulo superior de la ventana, y pulsa Cmd-Shift-I. Vers una ventana titulada "Window Attributes". Puedes, por ejemplo, marcar la casilla "Textured" y tu ventana cambiar a un aspecto metlico. Experimenta seleccionando los botones y el campo de texto: puedes modificar un montn de propiedades de tu aplicacin sin escribir una sola lnea de cdigo!

Nuestra ventana en Interface Builder, junto al inspector de objetos

Trabajando con clases


Cierra Interface Builder y volvamos ahora a Xcode. En la ventana de proyecto, abre la carpeta Classes en el panel Groups & Files. Vers dos ficheros, que son la clase bsica que Xcode ha creado para nosotros. El fichero terminado en ".h" es la cabecera (Header) con la interfaz de la clase; el que termina en ".m" es el fichero principal (Main) con la implementacin del cdigo de la clase.

08: Programas con entorno grfico

Pgina 8 de 21

Become an Xcoder Espaol v1.15

La clase Application Delegate que se incluye con cada aplicacin Cocoa. Cada aplicacin Cocoa necesita al menos una clase para poder realizar algo til. Por convenio a la clase bsica se la conoce como Delegada (Delegate), porque puede implementar una serie de mtodos delegados para personalizar el comportamiento de la clase NSApplication de Cocoa. Veremos esto ms tarde.

Las clases a fondo


Veamos como funcionan las clases. Para ahorrar esfuerzo de programacin, sera bueno que pudisemos construir encima de lo que otros ya han hecho, en lugar de empezar a escribir desde cero. Si, por ejemplo, queremos crear una ventana con unas propiedades especiales, slo deberamos necesitar aadir el cdigo para esas propiedades y no tener que escribir el cdigo para el resto del comportamiento de la ventana, como minimizar o cerrar. Para construir encima de lo que otros programadores han hecho, heredaremos todo ese comportamiento. Y eso es lo que hace a Objective-C tan diferente de C.

08: Programas con entorno grfico

Pgina 9 de 21

Become an Xcoder Espaol v1.15

Cmo se hace? Bien, tenemos una clase ventana (NSWindow), y nosotros podramos escribir una clase propia que herede de esa. Supongamos que aadimos una caracterstica adicional a nuestra clase. Qu ocurre cuando recibe un mensaje "close"? Nosotros no hemos escrito cdigo para eso, y tampoco lo hemos copiado de ningn sitio. Es sencillo, si la clase no contiene el cdigo para un mtodo en particular, el mensaje se transfiere automticamente a la clase desde la que hemos heredado (conocida como su "superclase") y si ah tampoco lo encontrase continuara buscndolo ascendiendo en la jerarqua de herencia. Si no se encuentra el mtodo, hemos recibido un mensaje que no podemos gestionar. Es como ir a un taller de coches para que nos arreglen la lavadora. No nos puede ayudar ni siquiera el jefe del taller. En estos casos Objective-C lanzar un error.

Personalizacin de clases
Qu ocurre si queremos implementar un comportamiento distinto para un mtodo que ya existe en la superclase? Es sencillo, podemos sobreescribir mtodos. Por ejemplo, podramos escribir cdigo para que cuando se pulse el botn para cerrar la ventana, que la mueva hacia fuera de la pantalla antes de cerrarla. Nuestra clase especial usar el mismo nombre de mtodo que la clase que defini Apple as que, cuando le llegue el mensaje de cerrar, se ejecutar nuestro cdigo y no el de Apple. Por tanto ahora la ventana saldr fuera de la vista antes de cerrarse realmente. Pero veamos, el cdigo para cerrar la ventana ya lo ha programado Apple, as que desde nuestro mtodo de cerrar ventana podramos invocar el mtodo de nuestra superclase. Veamos como hacerlo:
//[2] - (void) close:(id)sender { // Aqu escribiramos el cdigo para desplazar la ventana fuera de la pantalla. [super close]; // Esto invoca el mtodo "close" de la superclase. }

Una clase para gobernarlas a todas


La clase que est por encima de todas en la jerarqua de clases es la llamada NSObject. As que todas clases que nosotros podamos crear o usar van a ser subclases de NSObject, directa o indirectamente. Por ejemplo la clase NSWindow es una subclase de NSResponder, que a su vez es subclase de NSObject. La clase NSObject define los mtodos comunes a todos los objetos (por ejemplo, crear una descripcin textual del propio objeto, preguntar si el objeto es capaz de entender un mensaje dado, etc.) Antes de aburrirte con demasiada teora veamos como crear una clase.

Creacin de una clase


Dentro de nuestro proyecto Xcode seleccionaremos New File dentro del men File. Seleccionaremos Objective-C Class y subclass of NSObject. Pulsaremos el botn Next. Llamaremos a la clase "MPAClaseEjemplo". Pulsa el botn Finish.
08: Programas con entorno grfico Pgina 10 de 21

Become an Xcoder Espaol v1.15

Creacin de la clase MPAClaseEjemplo Despus de pulsar Finish vers dos ficheros nuevos en la carpeta Classes del panel Groups & Files: MPAClaseEjemplo.h y MPAClaseEjemplo.m; si las seleccionas podrs ver su contenido en el editor. En este momento tienen slo un esqueleto bsico. Recuerda que esta clase la creamos para que reciba los mensajes de los botones y enve tambin mensajes al campo de texto. Vamos a hacer que Interface Builder nos ayude a generar el cdigo. Las primeras 3 letras de MPAClaseEjemplo vienen de la abreviatura de Mi primera aplicacin. Puedes poner a las clases el nombre que quieras. Pero existe el convenio de que las clases empiecen por una o varias letras maysculas y no pueden contener espacios. Recomendamos que cuando empieces a escribir tus propias aplicaciones elijas 2 o 3 letras maysculas para usar como prefijo en el nombre de tus propias clases. Esto evitar confusiones con las clases existentes. Por ejemplo, no deberas usar NS, que est reservado para las clases de Apple (NS viene de NeXTStep, que es el sistema operativo en el que se bas Mac OSX cuando Apple compr la compaa NeXT. El wiki CocaDev mantiene la lista de prefijos que ya se estn usando y, por tanto, deberamos evitar. Comprubala antes de elegir tu propio prefijo: http://www.cocoadev.com/index.pl?ChooseYourOwnPrefix.

08: Programas con entorno grfico

Pgina 11 de 21

Become an Xcoder Espaol v1.15

Cuando se crean clases nuevas debemos elegir un nombre adecuado que proporcione informacin sobre la clase. Por ejemplo, ya hemos visto que la clase de Cocoa que representa las ventanas se llama NSWindow. Otro ejemplo podra ser la clase que representa colores, llamada NSColor. En nuestro caso, la clase MPAClaseEjemplo que estamos creando solamente va a ilustrar el sistema por el que los objetos se comunican entre ellos en una aplicacin. Por eso le damos un nombre genrico sin significado especial.

Creacin de una instancia en Interface Builder


Vuelve a Interface Builder (recuerda que lo abriremos haciendo doble-click en MainMenu.xib). En la ventana Library abre el desplegable superior y selecciona Objects & Controllers. Despus arrastra un Object (tiene el icono de un cubo azul) hasta la clase MainMenu.xib.

Instanciando un nuevo objeto

08: Programas con entorno grfico

Pgina 12 de 21

Become an Xcoder Espaol v1.15

Despus selecciona el botn Identity de la ventana Inspector (Cmd-6) y en la seccin Class Identity, en el desplegable Class selecciona MPAClaseEjemplo. De esta forma instanciaremos nuestra clase MPAClaseEjemplo dentro del fichero xib. Esto permitir la comunicacin entre nuestro cdigo y la interfaz.

Asignando la identidad a nuestro objeto

Creacin de conexiones
Nuestro primer paso va a ser crear conexiones entre los botones (que envan mensajes) hacia nuestra clase MPAClaseEjemplo. Adems, crearemos conexiones desde nuestra clase hacia el campo de texto, porque vamos a querer enviar mensajes a ese componente. Para poder enviar mensajes de un objeto a otro, el primero ha de tener una referencia al segundo, y eso es lo que conseguiremos creando una conexin. Veamos lo que queremos que haga la aplicacin. Al pulsarse cada botn, tiene que enviar un mensaje. Este mensaje contendr el nombre del mtodo de la clase MPAClaseEjemplo que queremos que se ejecute. El mensaje se enviar a la instancia de la clase MPAClaseEjemplo que acabamos de crear, es decir, un objeto MPAClaseEjemplo. (Recordemos que las

08: Programas con entorno grfico

Pgina 13 de 21

Become an Xcoder Espaol v1.15

instancias no contienen el cdigo, lo tienen las clases). Por lo tanto el mensaje que llega al objeto MPAClaseEjemplo dispara un mtodo en la clase MPAClaseEjemplo que har alguna cosa: en nuestro caso, enviar a su vez un mensaje al campo de texto que creamos en nuestra ventana de aplicacin. Al igual que todo mensaje, ste consiste en el nombre de un mtodo (que tendr que ejecutar el campo de texto). En este caso, el mtodo consiste en mostrar un valor, y ese valor ser tambin parte del mensaje (es, por tanto, un "argumento"; recuerdas el concepto?). Nuestra clase necesita dos acciones (mtodos) que sern llamadas por los objetos botn. Nuestra clase tambin necesita un Outlet: una variable para recordar el objeto al que se le va a enviar el mensaje (el campo de texto). En la ventana Library selecciona, en la parte superior, la pestaa Classes. Esto te mostrar todas las clases y sus atributos del Framework de Cocoa. En la parte inferior de la ventana hay un campo de bsqueda: comienza a escribir en l el nombre de tu clase (MPAClaseEjemplo) y la vers aparecer en el primer panel. El aspecto con el que aparece la clase puede ser distinto en tu ventana. Recuerda que se puede personalizar en el botn de rueda dentada de la parte inferior: aqu est activa la opcin "View icons and descriptions".

La clase MPAClaseEjemplo en la librera de clases

08: Programas con entorno grfico

Pgina 14 de 21

Become an Xcoder Espaol v1.15

Ahora, en la pestaa Actions, haz click en el botn con el signo (+) para aadir una accin (es decir, un mtodo de accin) a la clase MPAClaseEjemplo. Modifica el nombre que aparece por defecto por otro que tenga ms sentido (por ejemplo, puedes poner "asignarValor5:", ya que en este mtodo haremos que se muestre el nmero 5 en el campo de texto). Aade tambin otro mtodo y dale el nombre "anular:", ya que en este mtodo asignaremos un 0 al campo de texto. Fjate que el nombre de los mtodos siempre termina en dos puntos (":"). Lo explicaremos despus.

Creacin de mtodos en nuestra clase MPAClaseEjemplo Ahora selecciona la pestaa Outlets, pulsa el botn con el signo (+) para aadir un outlet y dale un nombre, por ejemplo "campoDeTexto".

08: Programas con entorno grfico

Pgina 15 de 21

Become an Xcoder Espaol v1.15

Creacin de un outlet en la clase MPAClaseEjemplo Antes de crear las conexiones entre objetos, vamos a darle nombres con sentido a nuestros botones. Por ejemplo, ya que el primero va a hacer que se muestre el valor 5 en el campo de texto, lo vamos a llamar "Asigna valor 5" (recordemos que para cambiar el nombre, la forma ms sencilla es hacer doble-click y escribir el nuevo nombre). De la misma forma, al segundo botn lo llamaremos "Anular". De todas formas ten en cuenta que lo que acabamos de hacer slo cumple una funcin esttica y no es estrictamente necesario para que el programa funcione. Pero debemos hacerlo para que el programa sea lo ms descriptivo posible al usuario final. Ahora estamos listos para crear las conexiones entre: 1. El botn "Anular" y la instancia de MPAClaseEjemplo 2. El botn "Asigna valor 5" y la instancia de MPAClaseEjemplo 3. La instancia de MPAClaseEjemplo y el campo de texto. Para crear las conexiones, presiona en el teclado la tecla Ctrl y arrastra el ratn desde el botn "Asigna valor 5" hasta la instancia de MPAClaseEjemplo en la ventana MainMenu.xib (asegrate de hacerlo en ese sentido y no desde la instancia hacia el botn!). Mientras nos

08: Programas con entorno grfico

Pgina 16 de 21

Become an Xcoder Espaol v1.15

desplazamos vers una lnea que se dibuja. Soltaremos el ratn encima de la instancia y se desplegar un men con las acciones que puede recibir la clase. Ah seleccionaremos "asignarValor5:".

Estableciendo la conexin Ahora el botn mantiene una referencia hacia nuestro objeto MPAClaseEjemplo y le enviar el mensaje asignarValor5: cuando sea pulsado. Conecta ahora el botn "Anular" siguiendo el mismo proceso (en el men que aparece cuando sueltas el ratn encima del objeto MPAClaseEjemplo debers seleccionar "anular:"). Para crear la conexin entre MPAClaseEjemplo y el campo de texto, pulsa la tecla Ctrl y empieza a arrastrar desde el objeto MPAClaseEjemplo y suelta el ratn encima del campo de texto. En el men que se despliega selecciona "campoDeTexto" (o el nombre que hayas escogido para el outlet). Para qu ha servido todo esto? Bien, en un momento veremos cmo se crear cdigo sin que hayamos tenido que escribir ni una sola lnea.

Generacin del cdigo


Asegrate de que en la ventana MainMenu.xib est seleccionada nuestra clase MPAClaseEjemplo. Ve al men File en Interface Builder y selecciona Write Class Files. Interface Builder preguntar dnde quieres que guarde los ficheros que se van a crear. No modifiques las opciones que aparecen por defecto, pulsa el botn Save y en la siguiente ventana pulsa Replace.

08: Programas con entorno grfico

Pgina 17 de 21

Become an Xcoder Espaol v1.15

Si vas ahora a Xcode, en la ventana de proyecto deberas ver los ficheros de tu clase en el grupo Classes. Si estuvieran en el grupo Resources o en otro diferente, basta con que selecciones los dos archivos y los arrastres al grupo Classes. Ahora selecciona el fichero .h de tu clase para verlo en el editor.

08: Programas con entorno grfico

Pgina 18 de 21

Become an Xcoder Espaol v1.15

Vemos en nuestro proyecto Xcode los ficheros generados Retrocedamos por un momento al captulo 3, en el que hablamos de las funciones. Recuerdas la cabecera de la funcin, como la que vemos en [11.1]? Es una especie de aviso para el compilador sobre lo que puede esperarse de la funcin. De los dos ficheros generados, uno tiene la extensin .h, indicando que es un fichero de cabecera (header en ingls): contiene informacin sobre la clase. Por ejemplo, vers que hay una lnea [3.3] que contiene NSObject, lo que quiere decir que nuestra clase hereda de la clase NSObject.
//[3] // MPAClaseEjemplo.h #import <Cocoa/Cocoa.h> // [3.2] @interface MPAClaseEjemplo : NSObject { // [3.3] IBOutlet id campoDeTexto; // [3.4] } - (IBAction)anular:(id)sender; // [3.6] - (IBAction)asignarValor5:(id)sender; // [3.7] @end

Vers que hay un outlet [3.4] que apunta al objeto campo de texto. id indica objeto. "IB" se refiere a Interface Builder, el programa que hemos usado para crear este cdigo.

08: Programas con entorno grfico

Pgina 19 de 21

Become an Xcoder Espaol v1.15

IBAction [3.6, 3.7] es equivalente a void. No se devuelve nada al objeto que enva un

mensaje: los botones de nuestro programa no obtienen una respuesta de nuestro objeto MPAClaseEjemplo al que envan su mensaje. Vers tambin que hay dos acciones de Interface Builder (IBAction). Son dos mtodos de nuestra clase. Los mtodos son bastante parecidos a las funciones pero hay algunas diferencias que veremos ms adelante. Anteriormente hemos visto #import <Foundation/Foundation.h> en lugar de la lnea [3.2]. La primera (Foundation) es para aplicaciones de consola (sin interfaz grfica) y sta (Cocoa) es para aplicaciones con GUI (Interfaz Grfica de Usuario). Ahora comprobemos el segundo fichero, el que tiene la extensin .m
//[4] // MPAClaseEjemplo.m #import "MPAClaseEjemplo.h" // [4.2] @implementation MPAClaseEjemplo - (IBAction)anular:(id)sender { //[4.4] } - (IBAction)asignarValor5:(id)sender { } @end

Antes de nada, vemos que hay una instruccin [4.2] para importar el fichero de cabecera. Podemos reconocer dos mtodos: anular: and asignarValor5:. Esos son los mtodos de nuestra clase. Se parecen a las funciones en que su cdigo debe escribirse entre llaves. En nuestra aplicacin, cuando se presiona un botn, ste enva un mensaje al objeto MPAClaseEjemplo, requiriendo la ejecucin de uno de los mtodos. No hemos tenido que escribir cdigo para ese comportamiento, slo hemos tenido que crear las conexiones en Interface Builder. Pero ahora tenemos que implementar los dos mtodos, es decir, escribir el cdigo que queremos que se ejecute dentro de cada uno. En nuestro caso queremos que enven un mensaje al campo de texto, lo que conseguiremos escribiendo las lneas [5.4, 5.7].
//[5] #import "MPAClaseEjemplo.h" @implementation MPAClaseEjemplo - (IBAction)anular:(id)sender { [campoDeTexto setIntValue:0]; // [5.4] } - (IBAction)asignarValor5:(id)sender { [campoDeTexto setIntValue:5]; // [5.7] } @end

Recomendamos volver un instante al comienzo de esta leccin, donde en [1] veamos el formato de las instrucciones para enviar mensajes. Como puedes ver, enviamos un mensaje al objeto referido en el outlet campoDeTexto. Al haber conectado mediante Interface Builder este outlet con el campo de texto, el mensaje se enviar al objeto correcto. El mensaje contiene el nombre de un mtodo, setIntValue:, junto a un valor numrico entero. El
08: Programas con entorno grfico Pgina 20 de 21

Become an Xcoder Espaol v1.15

mtodo setIntValue: tiene la capacidad de mostrar un valor entero en un objeto de campo de texto. En el siguiente captulo veremos como hemos averiguado la informacin sobre este mtodo.

Listo para despegar


Ahora lo tienes todo listo para compilar tu aplicacin y ejecutarla. Como ya sabes, pulsa el botn Build and Run. Xcode tardar unos segundos en compilar la aplicacin y despus la ejecutar: aparecer la ventana de tu aplicacin y podrs probarla.

Nuestra aplicacin funcionando Hemos creado con unos pocos pasos una aplicacin (eso s, muy bsica), en la que slo hemos tenido que escribir dos lneas de cdigo

08: Programas con entorno grfico

Pgina 21 de 21

Become an Xcoder Espaol v1.15

09: Bsqueda de mtodos


Introduccin
En el captulo anterior escribimos el cuerpo de dos mtodos por nosotros mismos, pero tambin usamos un mtodo de los que proporciona Apple, setIntValue:, que usamos para mostrar el valor de un nmero entero en un objeto campo de texto. Cmo podemos conocer qu mtodos hay disponibles? Recuerda que para cada mtodo que uses de los que proporciona Apple, no tendrs que escribir cdigo propio, con lo que hay menos posibilidad de que aparezcan errores. As que siempre vale la pena dedicar tiempo a conocer los mtodos que estn ya a nuestra disposicin antes de escribirlos por nosotros mismos.

Ejercicio
En Interface Builder, al seleccionar un objeto en la ventana "Library" (la que tiene una paleta con todos los objetos disponibles), en la parte inferior de esa ventana, debajo de su nombre descriptivo, aparece el nombre de su clase. Por ejemplo si seleccionas el objeto botn que empleamos en nuestra primera aplicacin leers "NSButton" y si seleccionas el campo de texto (es el que tiene el texto "Label") vers "NSTextField". Vamos a comprobar qu mtodos tiene disponible NSTextField. Vamos a Xcode y dentro del men Help seleccionamos "Developer documentation". En el campo de bsqueda de la parte superior derecha empieza a escribir NSTextField. Segn lo vas escribiendo, el panel izquierdo de la ventana muestra los resultados que coinciden con el texto y en el panel derecho aparece la informacin relativa al primero de esos resultados. Puedes dejar de escribir en cuanto veas en el panel izquierdo la clase NSTextField.

09: Bsqueda de mtodos

Pgina 1 de 4

Become an Xcoder Espaol v1.15

Navegando por la documentacin de Xcode. En lo primero que deberas fijarte es en la jerarqua de clases (en la seccin con el texto Inherits from). La que est ms a la derecha es, como ya comentamos en el captulo anterior, la clase padre de todas: NSObject. Si te desplazas hacia abajo en el documento encontrars el encabezado: Instance Methods Vamos a empezar aqu la bsqueda. Si echamos un vistazo a los mtodos disponibles nos damos cuenta de que no parece haber ninguno para asignar un valor al campo de texto. Tendremos que desplazarnos a la clase superior para buscarlo all. Segn pudimos ver en la jerarqua de clases, la clase inmediatamente superior a NSTextField es NSControl. Como la documentacin est en HTML hay hipervnculos, as que si hacemos click sobre NSControl en la vista de jerarqua de clases, aparecer la pgina de la clase NSControl. Desplazndonos hacia abajo por el documento encontramos el encabezado: Tasks (Tareas)

09: Bsqueda de mtodos

Pgina 2 de 4

Become an Xcoder Espaol v1.15

y ms abajo Setting the control's value (Asignar un valor al control) Eso es lo que queremos. Ah encontramos el mtodo: - setIntValue: Eso suena bien, as que hacemos click en el nombre del mtodo para que nos lleve a su documentacin.

setIntValue: Sets the value of the receivers cell using an integer.


- (void)setIntValue:(int)anInt

Parameters anInt The value of the cell interpreted as an integer. Discussion If the cell is being edited, this method aborts all editing before setting the value. If the cell does not inherit from NSActionCell, the method marks the cells interior as needing to be redisplayed; NSActionCell performs its own updating of cells.

En nuestra aplicacin, el objeto NSTextField es el receptor y tenemos que pasarle un entero. Esto lo podemos tambin comprobar en la firma del mtodo:
- (void)setIntValue:(int)anInt

En Objective-C, el signo menos (-) al comienzo indica que se trata de un mtodo de instancia (opuesto a un mtodo de clase, del que hablaremos ms adelante). void indica que no se devuelve nada al que invoca el mtodo. Despus de los dos puntos, (int) indica que la variable anInt debe ser un nmero entero. En nuestro ejemplo hemos invocado este mtodo pasndole un 5 y un 0 as que lo hemos hecho correctamente. No siempre es tan fcil encontrar el mtodo que se ajusta a lo que estamos buscando. Esto se te dar mejor cuanto ms uses la ayuda, as que sigue practicando.

09: Bsqueda de mtodos

Pgina 3 de 4

Become an Xcoder Espaol v1.15

Y cmo haras para leer el valor que hay en nuestro objeto campoTexto? Recuerdas en la leccin sobre funciones la caracterstica de que todas las variables en su interior estn aisladas del exterior? Lo mismo sucede con los mtodos. Por ello los objetos suelen tener un par de mtodos relacionados llamados "Accessors": uno para leer el valor y otro para asignarlo. Ya conocemos el ltimo: setIntValue:. El primero tiene este aspecto:
//[1] - (int) intValue

Como puedes ver en su firma, este mtodo devuelve un entero. As que si queremos leer el valor entero contenido en nuestro campo de texto deberamos enviar un mensaje como este:
//[2] int resultadoRecibido = [campoTexto intValue];

De nuevo, en funciones (y en mtodos) todas las variables estn aisladas. Eso es bueno para los nombres de variables, porque no hay que preocuparse de que al asignar un valor a una variable en una parte de nuestro programa, esto afecte a una variable con el mismo nombre dentro de otra funcin. Sin embargo, los nombres de funciones s que deben ser nicos en nuestro programa. Objective-C va un paso ms all: los nombres de mtodos debe ser nicos en la misma clase, pero clases distintas puede compartir nombres de mtodos. Esto es una caracterstica importante para escribir programas grandes, ya que los programadores pueden escribir cada uno sus clases sin preocuparse de que haya conflictos con los nombres de mtodos de las clases que escriban los dems. Pero hay ms. Se llama polimorfismo al hecho de que clases diferentes puedan tener los mismos nombres de mtodos y es una de las cosas que hacen tan especial la programacin orientada a objetos: te permite escribir trozos de cdigo sin que tengas que conocer previamente las clases de los objetos sobre las que se va a aplicar ese cdigo. Lo nico que se requiere es que, en el momento de la ejecucin del programa, los objetos comprendan los mensajes que se les envan. Aprovechando el polimorfismo podemos escribir aplicaciones flexibles y extensibles. Por ejemplo, en la aplicacin GUI que hemos creado, si reemplazsemos el campo de texto por otro objeto de cualquier clase capaz de comprender el mensaje setIntValue: la aplicacin seguira funcionando sin tener que modificar el cdigo, ni siquiera hara falta recompilarla. Incluso tenemos la capacidad de hacer el cambio de objeto en tiempo de ejecucin sin romper nada. Ah reside el poder de la programacin orientada a objetos.

09: Bsqueda de mtodos

Pgina 4 de 4

Become an Xcoder Espaol v1.15

10: awakeFromNib
Introduccin
Apple ha realizado un montn de trabajo por ti, facilitando la creacin de tus programas. En tu pequea aplicacin no has tenido que preocuparte de dibujar la ventana ni los botones, adems de muchas otras cosas. La mayor parte de ese trabajo reside en dos entornos de trabajo (frameworks). El Foundation Kit que importamos en el ejemplo [11] del captulo 4 aporta la mayora de los servicios que no estn asociados al interfaz grfico de usuario. El otro framework, llamado Application Kit, trata con los objetos que ves en pantalla y los mecanismos de interaccin con el usuario. Ambos estn bien documentados. Vayamos a la aplicacin GUI que montamos en el captulo 8. Supongamos que queremos mostrar un valor en el campo de texto en el momento en que se lanza la aplicacin y se muestra la ventana.

Ejercicio
Toda la informacin de la ventana se almacena en un fichero nib (nib viene de NeXT Interface Builder). Esto es un buen indicador de que el mtodo que necesitamos debe ser parte del Application Kit. Veamos como obtener informacin sobre este marco de trabajo. En Xcode, ve al men Help y selecciona Developer Documentation. En el campo de bsqueda (arriba a la derecha) escribe Application Kit. Veremos mltiples resultados en el panel izquierdo, entre ellos un documento titulado "Application Kit Framework Reference"; haremos click en esa lnea para que se abra el documento en el panel principal de la ventana de ayuda. En ese documento, bajo el encabezado "Protocol References" encontraremos un enlace con el texto NSNibAwaking. Al hacer click ah se abrir la documentacin de la clase NSNibAwaking.

NSNibAwaking Protocol Reference (informal protocol) Framework Declared in /System/Library/Frameworks/AppKit.framework


! !

Companion document Resource Programming Guide NSNibLoading.h

10: awakeFromNib

Pgina 1 de 2

Become an Xcoder Espaol v1.15

Overview This informal protocol consists of a single method, awakeFromNib. Classes can implement this method to initialize state information after objects have been loaded from an Interface Builder archive (nib file). Este protocolo consiste en un solo mtodo, awakeFromNib. Las clases pueden implementar este mtodo para inicializar su informacin de estado una vez que se han cargado los objetos desde un archivo de Interface Builder (fichero nib).

Si implementamos este mtodo, ser llamado cuando nuestro objeto se haya terminado de cargar desde el archivo nib. As que podemos utilizarlo para conseguir nuestro objetivo: mostrar un valor en el campo de texto en el momento en el arranca el programa. No quiero sugerir que sea siempre fcil encontrar el mtodo que estamos buscando. Frecuentemente requerir bastante indagacin y un uso adecuado de las palabras de bsqueda. Por esa razn es muy importante que te familiarices con la documentacin de ambos frameworks, as te hars una idea de los mtodos que tienes disponibles. Puedes no necesitarlo en este momento, pero te ayudar a hacerte una idea de como conseguir que tu programa haga lo que quieres. Bien, hemos encontrado nuestro mtodo, todo lo que necesitamos es aadirlo a nuestro fichero de implementacin MPAClaseEjemplo.m [1.9].
//[1] #import "MPAClaseEjemplo.h" @implementation MPAClaseEjemplo - (IBAction)anular:(id)sender { [campoDeTexto setIntValue:0]; } - (IBAction)asignarValor5:(id)sender { [campoDeTexto setIntValue:5]; } - (void)awakeFromNib { // [1.9] [campoDeTexto setIntValue:0]; } @end

Cuando se abra la ventana, se llamar automticamente al mtodo awakeFromNib. Como resultado el campo de texto mostrar un cero, que es lo que hemos codificado en el cuerpo del mtodo.

10: awakeFromNib

Pgina 2 de 2

Become an Xcoder Espaol v1.15

11: Punteros
Aviso!
Este captulo contiene conceptos avanzados y trata con elementos del lenguaje C que pueden intimidar a los principiantes. Si no los comprendes ahora, no te preocupes. Por suerte, aunque es til comprender cmo funcionan los punteros, no es esencial para empezar a programar con Objective-C.

Introduccin
Cuando se declara una variable, el Mac asocia esa variable con una zona de la memoria en la que va a almacenar su valor. Veamos, por ejemplo, la siguiente instruccin:
//[1] int x = 4;

Para poder ejecutarla, tu Mac busca espacio libre en su memoria y despus toma nota de que ese espacio es donde va a almacenar el contenido de la variable x (por supuesto deberamos haber usado un nombre ms descriptivo para esa variable). Mira la instruccin [1] de nuevo. Al indicar el tipo de variable (en este caso int) le hacemos saber al ordenador cuanto espacio se necesita para almacenar su valor. Si la variable fuese de tipo long long o double requerira ms espacio de almacenamiento. La instruccin de asignacin x = 4 almacena el nmero 4 en su espacio reservado. Por supuesto el ordenador recuerda en qu parte de su memoria est almacenado el valor de la variable x o, en otras palabras, cul es la direccin de la variable x. De esta forma, cada vez que usas x en tu programa, el ordenador va al lugar correcto (la direccin correcta) a recoger el valor de x. Un puntero es sencillamente una variable que contiene la direccin de otra variable.

Referenciar variables
Dada una variable, puedes obtener su direccin escribiendo & antes de su nombre. Por ejemplo, para obtener la direccin de x, escribiras &x. Cuando el ordenador evala la expresin x devuelve su valor (en nuestro caso obtenemos 4). Sin embargo cuando evala la expresin &x, devuelve la direccin de x, no el valor almacenado ah. La direccin es un nmero que indica un lugar especfico en la memoria del ordenador (igual que un nmero de habitacin indica una habitacin especfica en un hotel).

Uso de punteros
11: Punteros Pgina 1 de 3

Become an Xcoder Espaol v1.15

Los punteros se declaran as:


//[2] int *y;

Esta instruccin define una variable llamada y que contendr la direccin de una variable de tipo int. Repetimos: no va a contener un variable de tipo int, sino la direccin de esa variable. Para almacenar en la variable y la direccin en la que est almacenado el contenido de la variable x (para almacenar en y la direccin de x), escribiramos:
//[3] y = &x;

Ahora y "apunta a" la direccin de x, por tanto podemos usar y para localizar x. Veamos como: Dado un puntero, podemos obtener la variable a la que apunta escribiendo un asterisco (*) delante del puntero. Por ejemplo, al evaluar la expresin:
*y

obtendremos en este caso 4. Esto es equivalente a evaluar la expresin x. Y la siguiente instruccin:


*y = 5

es equivalente a:
x = 5

Los punteros son tiles porque a veces no quieres trabajar con el valor de una variable sino con su direccin. Por ejemplo, si queremos programar una funcin que incremente en 1 el valor de una variable, podras resolverlo de la siguiente forma?
//[4] void incrementa(int x) { x = x + 1; }

Realmente, no. Si llamas a esta funcin desde un programa, no obtendras el resultado que esperas:
//[5] int miValor = 6; incrementa(miValor); NSLog(@"%d:\n", miValor);

Este cdigo mostrara 6 en tu pantalla Adivinas por qu? Has incrementado miValor al llamar a la funcin? No, no lo has hecho. Como puedes ver, la funcin recoge el valor que se le ha pasado en miValor, es decir, el nmero 6, le suma 1 y , se deshace de l. Las
11: Punteros Pgina 2 de 3

Become an Xcoder Espaol v1.15

funciones slo trabajan con los valores que se les pasan, no con las variables que contienen esos valores. Por tanto las modificaciones producidas dentro de la funcin se pierden cuando se sale de la funcin. Es ms, imaginemos que no pasamos una variable, podramos pasar directamente un valor; si llamsemos a la funcin con incrementa(5); qu es lo que esperamos que se incremente? As que si esperas una funcin de incremento que realmente funcione, es decir, que acepte una variable como argumento y que realmente incremente el valor contenido en esa variable, vas a necesitar pasar la direccin de esa variable. De esa forma podrs modificar lo que est contenido en esa variable. Por tanto la solucin est en pasar como argumento un puntero:
//[6] void incrementa(int *y) { *y = *y + 1; }

Y tendras que llamar a la funcin as:


[7] int miValor = 6; incrementa(&miValor); // pasamos la direccin // Ahora miValor contiene el valor 7

11: Punteros

Pgina 3 de 3

Become an Xcoder Espaol v1.15

12: Cadenas de caracteres


Introduccin
Hasta ahora hemos visto varios tipos de datos bsicos: int, long, float, double, BOOL. Y en el anterior captulo hemos presentado los punteros. Aunque hemos usado cadenas de caracteres, slo lo hicimos con respecto a la funcin NSLog(). Esta funcin nos permite enviar una cadena a la pantalla, reemplazando los cdigos que empiezan por el signo (%), como por ejemplo %d, por un valor (repasar si es necesario el captulo 4).
//[1] float valorDePi = 3.1416; NSLog(@"Esto son tres ejemplos de impresin en pantalla de cadenas de caracteres.\n"); NSLog(@"Pi se aproxima a %10.4f.\n", valorDePi); NSLog(@"El nmero de caras de un dado es %d.\n", 6);

No hemos hablado antes de las cadenas por una buena razn. A diferencia de int o float, las cadenas son verdaderos objetos, creados a partir de la clase NSString o de la clase NSMutableString. Vamos a conocer estas clases, empezando por NSString.

NSString
De nuevo con los punteros
//[2] NSString *ordenadorFavorito; // [2.1] ordenadorFavorito = @"Mac!"; NSLog(ordenadorFavorito);

Probablemente entiendas la segunda lnea, pero la primera requiere alguna explicacin. Recuerdas que, cuando declaramos una variable puntero, debemos indicar a qu tipo de dato apunta? Repasemos la sentencia del captulo 11.
//[3] int *y;

Aqu indicamos que la variable puntero y contiene la direccin de una zona de memoria en la que se puede encontrar un entero. En [2.1] le indicamos al compilador que la variable puntero ordenadorFavorito contiene la direccin de memoria en la que se puede encontrar un objeto de tipo NSString. Usamos un puntero para guardar nuestra cadena porque en Objective-C lo objetos no se manipulan directamente, sino siempre a travs de punteros a dichos objetos. No te preocupes demasiado si no comprendes esto, no es crucial. Lo que s debes recordar es referirte siempre a una instancia de NSString o NSMutableString (o cualquier otro objeto) usando el asterisco (*).

12: Cadenas de caracteres

Pgina 1 de 6

Become an Xcoder Espaol v1.15

El smbolo @
Por qu vemos siempre el signo @ delante de la cadenas de caracteres? Bien, Objective-C es una extensin del lenguaje C, que tiene su propia forma de tratar con cadenas. Para diferenciar el nuevo tipo de cadenas, que son objetos en toda su extensin, Objective-C coloca delante un signo @.

Un nuevo tipo de cadena


En qu mejoran las cadenas de Objective-C con respecto a las de C? En primer lugar las cadenas de Objective-C son Unicode en lugar de ASCII, lo que implica que pueden representar caracteres de cualquier lenguaje, por ejemplo el chino, adems de, por supuesto, nuestro alfabeto.

Ejercicio
Podemos, en una sola instruccin, declarar y asignar valor a una cadena[4].
//[4] NSString *actrizFavorita = @"Julia";

La variable puntero actrizFavorita apunta a la posicin de memoria en la que se aloja el objeto que contiene la cadena "Julia". Una vez que se le ha dado un valor a la cadena, se le podra asignar otro valor, pero no se puede modificar la propia cadena [5.7], porque es una instancia de la clase NSString. Enseguida aclaramos esto.
//[5] #import <foundation/foundation.h> int main (int argc, const char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSString *ordenadorFavorito; ordenadorFavorito = @"iBook"; // [5.7] ordenadorFavorito = @"MacBook Pro"; NSLog(@"%@", ordenadorFavorito); [pool release]; return 0; }

Cuando se ejecuta, el programa imprime:


MacBook Pro

La cadena no se puede modificar, pero lo que s se puede hacer (y de hecho acabamos de hacerlo) es reemplazar la cadena por otra.

NSMutableString
12: Cadenas de caracteres Pgina 2 de 6

Become an Xcoder Espaol v1.15

A una cadena de la clase NSString la llamamos inmutable, porque no se puede modificar. Lo que esto significa es que no se pueden alterar los caracteres individuales del texto que la compone. Y qu tiene de bueno una cadena que no se puede modificar? Bien, la ventaja es que son ms fciles de manejar por el sistema operativo, as que el programa correr ms rpido. Adems vers que cuando hagas tus propios programas, encontrars pocas ocasiones en las que necesites modificar cadenas. Por supuesto, hay veces en que necesitas modificar las cadenas, y para eso tenemos la clase NSMutableString. La vamos a ver ms adelante en este captulo.

Ejercicio
Antes quiero asegurarme de que comprendes que las cadenas son objetos. Si son objetos, entonces podemos enviarles mensajes. Por ejemplo, vamos a enviar el mensaje "length" (longitud) a un objeto cadena [6].
//[6] #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int longitud; NSString * foo; foo = @"Julia!"; longitud = [foo length]; // [6.10] NSLog(@"La longitud es %d.", longitud); [pool release]; return 0; }

Cuando se ejecuta, este programa muestra:


La longitud es 7.

Con frecuencia vas a encontrar en documentos en ingls que los programadores tienen la costumbre de llamar foo y bar a las variables de sus ejemplos. Realmente se consideran nombres no apropiados ya que no son descriptivos, igual que pasa con el nombre de variable x. Los usamos aqu para que los conozcas cuando los encuentres en otros ejemplos por internet. En la lnea [6.10] enviamos el mensaje length al objeto foo. Este mtodo est definido as en la clase NSString:

- (unsigned int)length

12: Cadenas de caracteres

Pgina 3 de 6

Become an Xcoder Espaol v1.15

Returns the number of Unicode characters in the receiver. (devuelve el nmero de caracteres Unicode del receptor.

Podras tambin querer cambiar el texto a maysculas [7]. El mensaje que tendras que enviar es entonces uppercaseString, que tambin podras encontrar por ti mismo en la documentacin (lee los mtodos de instancia disponibles para la clase NSString). Al recibir este mensaje, el objeto devuelve otro objeto NSString con el mismo contenido pero con cada carcter convertido a mayscula.
//[7] #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *foo, *bar; foo = @"Julia!"; bar = [foo uppercaseString]; NSLog(@"%@ se converte a %@.", foo, bar); [pool release]; return 0; }

Si lo ejecutas, mostrar:
Julia! se converte a JULIA!

A veces podras querer modificar el contenido de una cadena en lugar de crear una nueva. En tal caso tendras que alojar tu texto en un objeto de la clase NSMutableString, que trae varios mtodos para modificar el contenido. Por ejemplo, el mtodo appendString: aade la cadena pasada como argumento al final del receptor.
//[8] #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // [8.5] NSMutableString *foo; foo = [@"Julia!" mutableCopy]; // [8.6] [foo appendString:@" estoy feliz"]; NSLog(@"Aqu est el resultado: %@.", foo); [pool release]; return 0; }

Cuando se ejecute, el programa mostrar:


Aqu est el resultado: Julia! estoy feliz.

En la lnea [8.6] el mtodo mutableCopy (que est disponible en la clase NSString) crea y devuelve una cadena modificable con el mismo contenido que el receptor del mensaje. As

12: Cadenas de caracteres

Pgina 4 de 6

Become an Xcoder Espaol v1.15

que despus de la ejecucin de la lnea [8.6], la variable foo apunta a un objeto de cadena modificable que contiene el texto "Julia!".

De nuevo ms punteros
Comentamos al comienzo del captulo que en Objective-C no se usan los objetos directamente sino que siempre se referencian mediante punteros a ellos. Y esa es la razn por la que usamos la notacin de puntero en la lnea [8.5]. Realmente, cuando usamos la palabra "objeto" en Objective-C lo que queremos decir es "puntero a un objeto". Pero como siempre accedemos a los objetos mediante punteros se ha terminado abreviando simplemente con la palabra "objeto". El hecho de que siempre se usen mediante punteros tiene una implicacin importante que debemos conocer: ms de una variable pueden referenciar el mismo objeto al mismo tiempo. Por ejemplo, despus de la lnea [8.6] la variable foo referencia a un objeto que representa la cadena "Julia!", algo que podramos representar con el siguiente diagrama:

Los objetos siempre se usan mediante punteros Ahora supongamos que asignamos el valor de foo a la variable bar de esta forma:
bar = foo;

El resultado de esto es que tanto foo como bar apuntan al mismo objeto:

Mltiples variables pueden referenciar el mismo objeto En esta situacin, enviar un mensaje a foo (por ejemplo [foo length];) tiene el mismo efecto que enviar un mensaje a bar (por ejemplo [bar length];), tal como se muestra en el siguiente ejemplo:

12: Cadenas de caracteres

Pgina 5 de 6

Become an Xcoder Espaol v1.15

//[9] #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSMutableString *foo = [@"Julia!" mutableCopy]; NSMutableString *bar = foo; NSLog(@"foo apunta a la cadena: %@.", foo); NSLog(@"bar apunta a la cadena: %@.", bar); NSLog(@"\n"); [foo appendString:@" estoy feliz"]; NSLog(@"foo apunta a la cadena: %@.", foo); NSLog(@"bar apunta a la cadena: %@.", bar); [pool release]; return 0; }

Cuando se ejecuta el programa, muestra:


foo bar foo bar apunta apunta apunta apunta a a a a la la la la cadena: cadena: cadena: cadena: Julia!. Julia!. Julia! estoy feliz. Julia! estoy feliz.

El poder tener referencias al mismo objeto desde diferentes lugares al mismo tiempo es una caracterstica esencial de los lenguajes orientados a objetos. Realmente ya lo habamos usado previamente. Por ejemplo, en el captulo 8, referenciamos el objeto MPAClaseEjemplo desde dos objetos botn diferentes.

12: Cadenas de caracteres

Pgina 6 de 6

Become an Xcoder Espaol v1.15

13: Arrays
Introduccin
A veces necesitas manejar conjuntos de datos. Por ejemplo podras necesitar tener una lista de cadenas de texto. Podra ser bastante molesto usar una variable para cada una de esas cadenas. Por supuesto hay una solucin mejor: el array. Un array es una lista ordenada de objetos (o, ms exactamente, una lista de punteros a objetos). Puedes aadir objetos al array, eliminarlos o preguntarle qu objeto est almacenado en determinado ndice (es decir, en una determinada posicin). Tambin puedes preguntarle cuntos elementos contiene. Cuando contamos elementos, generalmente comenzamos a contar por 1. Pero en los arrays el primer elemento tiene el ndice 0, el segundo tiene ndice 1 y as sucesivamente.

Ejemplo: un array que contiene tres strings Ms tarde veremos ejemplos de cdigo, que nos permitirn entender el efecto de empezar a contar por 0. Tenemos dos clases para manejar arrays: NSArray y NSMutableArray. Igual que con las cadenas, hay una versin mutable y una inmutable. En este captulo vamos a usar la versin mutable. stos son arrays exclusivos de Objective-C y Cocoa. Hay tambin un tipo simple de array propio del lenguaje C (y por tanto tambin parte de Objective-C) del que no vamos a hablar aqu. Te lo advertimos por si ms tarde lees algo sobre los arrays de C, que no tienen nada que ver con las clases NSArray y NSMutableArray.

Un mtodo de clase
Una forma de crear un array es ejecutar una instruccin como esta:
[NSMutableArray array];

Esto crear y devolver un array vaco. Pero espera un minuto esto es extrao, no? Estamos usando una clase (NSMutableArray) como receptora de un mensaje y hasta ahora siempre habamos enviado mensajes a instancias (es decir, a objetos), no a clases.

13: Arrays

Pgina 1 de 4

Become an Xcoder Espaol v1.15

Bien, pues acabamos de aprender algo nuevo: el hecho de que tambin podemos llamar a mtodos de las clases (y eso se debe a que las clases son tambin objetos, instancias de lo que se llaman metaclases, pero no vamos a ir ms all en este artculo de introduccin). No tenemos que preocuparnos de liberar la memoria ocupada al alojar este objeto, ya que se produce automticamente por estar vinculado a un NSAutoreleasePool (ver el cdigo que se genera automticamente relativo al NSAutoreleasePool en nuestros programas Xcode). Al llamar al mtodo de clase estamos haciendo algo equivalente a:
NSMutableArray *lista = [[[NSMutableArray alloc] init] autorelease];

En caso de que quisieras que el array permaneciera en memoria despus de que se libere el objeto NSAutoreleasePool deberas enviar un mensaje -retain a la instancia. En la documentacin de Cocoa, los mtodos de clase estn precedidos de un smbolo "+", en lugar del smbolo "-" que hemos visto hasta ahora para los mtodos de instancia (ver por ejemplo el captulo 8, [4.4]). Por ejemplo, en la documentacin del mtodo "array" leemos:

array + (id)array Creates and returns an empty array. This method is used by mutable subclasses of NSArray. See Also: + arrayWithObject:, + arrayWithObjects:

Ejercicio
Vamos a escribir cdigo. El siguiente programa crea un array vaco, almacena en l tres cadenas y despus muestra el nmero de elementos en el array.
//[1] #import <foundation/foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSMutableArray *miArray = [NSMutableArray array]; [miArray addObject:@"primera cadena"]; [miArray addObject:@"segunda cadena"]; [miArray addObject:@"tercera cadena"]; int cantidad = [miArray count]; NSLog(@"Hay %d elementos en mi array", cantidad); [pool release]; return 0; }

Cuando se ejecute, este programa mostrar:

13: Arrays

Pgina 2 de 4

Become an Xcoder Espaol v1.15

Hay 3 elementos en mi array

El siguiente programa es como el anterior excepto que muestra la cadena almacenada en el ndice 0 del array. Para obtenerla, usaremos el mtodo objectAtIndex: [2.9].
//[2] #import <foundation/foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSMutableArray *miArray = [NSMutableArray array]; [miArray addObject:@"primera cadena"]; [miArray addObject:@"segunda cadena"]; [miArray addObject:@"tercera cadena"]; NSString *elemento = [miArray objectAtIndex:0]; // [2.9] NSLog(@"El elemento en el ndice 0 del array es: %@", elemento); [pool release]; return 0; }

Cuando se ejecute, mostrar:


El elemento en el ndice 0 del array es: primera cadena

A veces tienes que recorrer un array para hacer algo con cada uno de sus elementos. Para ello puedes usar un bucle como el que mostramos a continuacin, en el que mostramos cada elemento del array adems de su ndice:
//[3] #import <foundation/foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSMutableArray *miArray = [NSMutableArray array]; [miArray addObject:@"primera cadena"]; [miArray addObject:@"segunda cadena"]; [miArray addObject:@"tercera cadena"]; int i; int cantidad; for (i = 0, cantidad = [miArray count]; i < cantidad; i = i + 1) { NSString *elemento = [miArray objectAtIndex:i]; NSLog(@"El elemento en el ndice %d del array es: %@", i, elemento); } [pool release]; return 0; }

Cuando se ejecute, el programa mostrar:


El elemento en el ndice 0 del array es: primera cadena El elemento en el ndice 1 del array es: segunda cadena El elemento en el ndice 2 del array es: tercera cadena

13: Arrays

Pgina 3 de 4

Become an Xcoder Espaol v1.15

Ten en cuenta que los arrays no estn limitados a contener cadenas. Pueden contener cualquier objeto que quieras. Las clases NSArray y NSMutableArray proporcionan otros muchos mtodos, y recomendamos que mires la documentacin de estas clases para aprender ms sobre arrays. Terminaremos este captulo hablando del mtodo que permite reemplazar un objeto por otro en un ndice determinado. Este mtodo se llama replaceObjectAtIndex:withObject:. Hasta ahora hemos utilizado mtodos que requieren como mucho un argumento. Pero ste es diferente porque necesita dos argumentos, tal como puedes advertir al tener dos caracteres "dos puntos (:)" en el nombre del mtodo. Vamos a ver cmo usar este mtodo:
//[4] [miArray replaceObjectAtIndex:1 withObject:@"Hola"];

Despus de la ejecucin, en el ndice 1 estar la cadena @"Hola". Por supuesto slo se debe llamar a este mtodo con un ndice vlido, es decir, debe haber ya un objeto en ese ndice para que pueda ser sustituido por el objeto que le pasamos.

Conclusin
Como puedes ver, los nombres de mtodos en Objective-C son como instrucciones con espacios vacos en medio (precedidos del carcter "dos puntos"). Cuando invocas al mtodo debes insertar el valor en esos espacios, creando una instruccin llena de sentido. Esta sintaxis de nombre e invocacin de mtodos viene del lenguaje Smalltalk y es uno de los logros ms importantes de Objective-C, ya que hace el cdigo muy expresivo. Cuando crees tus propios mtodos deberas recordar llamarlos de forma que crees una instruccin con pleno significado cuando se llamen. Esto har el cdigo ms legible, lo que facilitar el mantenimiento posterior de los programas.

13: Arrays

Pgina 4 de 4

Become an Xcoder Espaol v1.15

14: Accessorios y propiedades


Introduccin
Hemos visto que un objeto puede ser visible, por ejemplo una ventana o un campo de texto; o invisible, como un array o un controlador que responde a acciones del interfaz de usuario. As que qu es exactamente un objeto? En esencia un objeto consta de una serie de valores (lo que llamamos variables) y realiza algunas acciones (lo que llamamos mtodos). Un objeto contiene y transforma datos. Podemos concebir un objeto como un pequeo ordenador, que enva y responde a mensajes. Tu programa sera una especie de red en la que todos esos pequeos ordenadores trabajan juntos para producir el resultado deseado.

Composicin de objetos
El trabajo de un programador Cocoa es crear clases que contengan otros objetos (como cadenas de texto, arrays y diccionarios) en los que se almacenan los valores que necesita la clase para hacer su trabajo. Algunos de esos objetos se crearn, usarn y destruirn aisladamente dentro de un mtodo. Pero otros ser necesario que permanezcan durante todo el ciclo de vida del objeto. A estos ltimos objetos se les llama variables de instancia o propiedades de la clase. La clase puede tambin definir mtodos que trabajen con estas variables. A esta tcnica se le llama composicin de objetos. Estos objetos compuestos generalmente heredan directamente de NSObject. Por ejemplo, una clase controladora de una calculadora podra contener como variables de instancia: un array de objetos botn y un campo de texto para el resultado. Tambin podra contener mtodos para sumar, restar, multiplicar y dividir nmeros y mostrar el resultado en el GUI. Las variables de instancia de declaran en el fichero de cabecera de la clase. En el ejemplo de nuestra calculadora sera algo as:
//[1] @interface MiControladorDeCalculadora : NSObject { //Variables de instancia NSArray * botones; NSTextField * campoResultado; } //Mtodos - (NSNumber *)mutiplica:(NSNumber *)valor; - (NSNumber *)suma:(NSNumber *)valor; - (NSNumber *)resta:(NSNumber *)valor; - (NSNumber *)divide:(NSNumber *)valor; @end

14: Accesorios y Propiedades

Pgina 1 de 4

Become an Xcoder Espaol v1.15

Encapsulacin
Uno de los objetivos de la programacin orientada a objetos es la encapsulacin: hacer cada clase lo ms autocontenida y reutilizable posible. Si recordamos el captulo 3, las variables dentro de bucles, funciones y mtodos estn aisladas del exterior. Este aislamiento tambin vale para los objetos. Esto significa que desde el exterior no podemos acceder a las variables de instancia de otros objetos, no estn disponibles nada ms que para los propios mtodos de la clase. Pero a veces necesitamos desde otros objetos modificar las variables de instancia de un objeto. Cmo hacerlo? Los mtodos s estn disponibles desde fuera de un objeto. Todo lo que tenemos que hacer es enviar un mensaje al objeto para disparar ese mtodo. As que para tener disponible determinada variable crearemos un par de mtodos para leer y modificar esa variable de instancia. A este par de mtodos se les llama colectivamente accessors (accededores). En el captulo 8 descubrimos el mtodo setIntValue: de la clase NSTextField. Este mtodo hace pareja con el mtodo intValue (setIntValue asigna el valor e intValue lee el valor). Juntos forman dos de los mtodos accessor de NSTextField.

Accessors
Qu aspecto tiene esto en el cdigo? Veamos el siguiente ejemplo.
//[2] @interface MiPerro : NSObject { //[2.2] NSString * _nombre; } - (NSString *)nombre; - (void)setNombre:(NSString *)valor; @end

Esta interfaz de la clase MiPerro tiene una variable de instancia, una cadena de texto llamada _nombre [2.2]. Para poder leer y cambiar el nombre del perro (almacenado en la variable de instancia _nombre), hemos definido dos mtodos: nombre y setNombre:. La implementacin sera algo as:
//[3] @implementation MiPerro - (NSString *)nombre { return _nombre; //[3.3] } - (void)setNombre:(NSString *)valor { _nombre = valor; //[3.6] } @end

14: Accesorios y Propiedades

Pgina 2 de 4

Become an Xcoder Espaol v1.15

En el primer mtodo [3.3] devolvemos simplemente la variable de instancia. En el segundo mtodo [3.6] asignamos a la variable de instancia el valor pasado como argumento. Hemos simplificado la implementacin por claridad, lo habitual es aadir cdigo para gestin de memoria dentro de estos mtodos. En el ejemplo 4 vemos un ejemplo ms real:
//[4] @implementation MiPerro - (NSString *)nombre { return [[_nombre retain] autorelease]; } - (void)setNombre:(NSString *) valor { if (_nombre != valor) { [_nombre release]; _nombre = [valor copy]; } } @end

No vamos a entrar en detalle sobre este cdigo (ver el captulo 15), pero podramos decir que el cdigo en [4] es equivalente a [3], ms instrucciones para copiar, retener y liberar memoria. Las instrucciones de gestin de memoria varan segn el tipo de dato. No se recomienda usar el guin delante del nombre de las variables, lo hemos puesto por claridad en nuestro ejemplo con la variable de instancia _nombre, pero podramos haberlo llamado igual que el mtodo (nombre) y no habra conflicto ya que variables y mtodos usan espacios de nombres diferentes.

Propiedades
Con Leopard y Objective-C 2.0 aparecen nuevas caractersticas que permiten economizar cuando usamos patrones de cdigo habituales. La nueva caracterstica de la que estamos hablando se llama propiedades. Con ella el ahorro de cdigo es significativo y ello implica por supuesto menos cdigo que depurar en caso de errores. En qu se diferencian las propiedades de los accessors? En esencia, las propiedades sintetizan directamente los accessors, usando la ms apropiada y eficiente gestin de memoria. En otras palabras, escriben los mtodos accessor por ti, aunque el cdigo de estos mtodos no queda a la vista. El ejemplo [2] usando propiedades quedara as:
//[5] @interface MiPerro : NSObject { NSString * nombre; } @property (copy) NSString *nombre; @end

Y la implementacin quedara as:


//[6] @implementation MiPerro

14: Accesorios y Propiedades

Pgina 3 de 4

Become an Xcoder Espaol v1.15

@synthesize nombre; @end

Puedes comprobar que el cdigo se ha simplificado realmente. Si resulta que tu clase tiene muchas variables que necesitan accessor, imagnate lo que te facilita la vida el uso de propiedades.

14: Accesorios y Propiedades

Pgina 4 de 4

Become an Xcoder Espaol v1.15

15: Gestin de memoria


Presentacin
Es el momento de explicar las sentencias que haban quedado pendientes hace ya varios captulos. Esas instrucciones trabajan con la memoria. Tu programa no es el nico que va estar ejecutndose en tu Mac y la memoria es un bien valioso. Por tanto cuando tu programa no necesite la memoria que ha requerido debe devolverla al sistema. As que cuando tu madre te deca que debas ser educado y vivir en armona con la comunidad te estaba enseando a programar!. Incluso si tu programa fuese el nico ejecutndose, la memoria no liberada ira arrinconando a tu programa hacindolo ir a paso de tortuga.

Recoleccin de basura
Las tcnicas de gestin de memoria que usa Cocoa y que se explican ms adelante en este captulo se llaman recuento de referencias (Reference Counting). Encontrars explicaciones ms completas en libros o artculos ms avanzados (ver captulo 15). Mac OS X 10.5 Leopard presenta un nuevo sistema de gestin de memoria para Objective-C 2.0, llamado Recoleccin de basura de Cocoa (Garbage Collection). La recoleccin de basura gestiona la memoria automticamente, eliminando la necesidad de retener, liberar o autoliberar los objetos explcitamente. La magia de la recoleccin de basura trabaja con todos los objetos de Cocoa que heredan de NSObject o NSProxy y permite al programador escribir menos cdigo que en versiones anteriores de Objective-C. En la prctica no hay mucho ms que decir, puedes olvidar todo lo que has aprendido en este captulo.

Activar la recoleccin de basura


Es necesario activar la recoleccin de basura, ya que por defecto est apagada en cada proyecto nuevo de Xcode. Para ello selecciona el nombre de tu proyecto en el panel Groups & Files y pulsa el botn Info. En el panel de botones superior selecciona Build y en el filtro de bsqueda de ajustes (Search in build settings) empieza a escribir garbage collection. Vers aparecer el ajuste con el valor Unsupported. Puedes seleccionar "Supported" o "Required". La primera opcin permite que en tu programa coexistan el sistema clsico de retener/liberar memoria junto a la recoleccin de basura automtica. La segunda opcin obliga a que todos los mdulos de tu programa usen nicamente la recoleccin de basura automtica.

Recuento de referencias: el ciclo de vida del objeto


Si te interesan las tcnicas de gestin de memoria anteriores a Leopard, sigue leyendo.

15: Gestin de memoria

Pgina 1 de 3

Become an Xcoder Espaol v1.15

Cuando tu programa crea un objeto, el objeto ocupa un espacio en memoria y debes liberar ese espacio cuando el objeto ya no se use ms, es decir, deberas destruir el objeto. El problema es que no siempre es fcil determinar cuando el objeto deja de ser usado. Por ejemplo, durante la ejecucin del programa, tu objeto puede ser referenciado por muchos otros objetos y no debera por tanto destruirse mientras haya la posibilidad de que cualquiera de esos objetos lo vayan a usar (intentar usar un objeto que ha sido destruido puede hacer que tu programa rompa o se comporte de forma impredecible).

La cuenta de retencin
Para ayudar a destruir objetos que ya no son necesarios, Cocoa asigna un contador a cada objeto, que representa su "cuenta de retencin". As que en tu programa, cuando referencias un objeto, deberas incrementar la cuenta de retencin en 1. Y cuando eliminas la referencia a un objeto, deberas decrementar la cuenta de retencin. Cuando la cuenta de retencin de un objeto es igual a 0, el objeto sabe que nadie lo referencia y por tanto se autodestruye con seguridad, liberando la memoria asociada. Por ejemplo, supongamos que tu aplicacin es un reproductor de msica y que tiene objetos que representan canciones y listas de reproduccin. Supongamos que una cancin est en tres listas de reproduccin. Si no est referida en ningn otro sitio, entonces el valor de la cuenta de retencin de la cancin es igual a 3.

Un objeto conoce cuantas veces est referenciado por otros objetos gracias a su cuenta de retencin

Retain y Release
Para incrementar la cuenta de retencin de un objeto, lo que debemos es enviarle el mensaje retain.

15: Gestin de memoria

Pgina 2 de 3

Become an Xcoder Espaol v1.15

[miObjeto retain];

Para decrementar la cuenta de retencin de un objeto, le enviamos el mensaje release.


[miObjeto release];

Autorelease
Cocoa tambin ofrece un mecanismo llamado "pool de autorelease", que permite enviar un mensaje de liberacin retardada a un objeto. Para usarlo, debes registrar el objeto en lo que se llama "pool de autorelease", envindole un mensaje autorelease.
[miObjeto autorelease];

El pool de autorelease se ocupar de enviar el mensaje de liberacin a tu objeto cuando sea conveniente. Las sentencias que tratan con los pool de autorelease que pudimos ver en captulos anteriores se ocupan de ajustar correctamente toda esta maquinaria de autoliberacin de objetos.

15: Gestin de memoria

Pgina 3 de 3

Become an Xcoder Espaol v1.15

16: Fuentes de informacin


El modesto objetivo de este libro era ensearte los principios de Objective-C en el entorno Xcode. Si has repasado su contenido al menos un par de veces y has probado los ejemplos realizando tus propias variaciones, entonces ests preparado para escribir las aplicaciones que desees crear. Este libro te ha dado suficiente conocimiento para meterte pronto en problemas. Ests listo para explotar otros recursos y podras empezar por los que se listan a continuacin. Un aviso importante antes de que empieces a escribir tu cdigo: no empieces inmediatamente! Echa un vistazo a los marcos de trabajo, ya que Apple puede haber hecho ya el trabajo por ti, o al menos suministrar clases que requieran poco esfuerzo por tu parte para satisfacer tus necesidades. Tambin puede que otros hayan trabajado en lo que necesites y tengan el cdigo fuente disponible. As que ahorra tu propio tiempo consultando la documentacin y buscando en internet. El primer sitio debera ser la web de desarrollo de Apple en http://developer.apple.com/ Te recomendamos tambin que aadas a tus marcadores:
http://osx.hyperjeff.net/reference/CocoaArticles.php http://www.cocoadev.com/ http://www.cocoadevcentral.com/ http://www.cocoabuilder.com/ http://www.stepwise.com/

Estos sitios enlazan a otros muchos lugares y fuentes de informacin. Tambin podras suscribirte a la lista de correo de desarrollo Cocoa en http://lists.apple.com/mailman/listinfo/cocoa-dev. Este es un lugar en el que puedes plantear tus preguntas y sus miembros harn todo lo posible por ayudarte. Antes de formular tu pregunta lee los archivos por si otros ya la han hecho antes en http://www.cocoabuilder.com/. Sigue estos consejos para hacer preguntas de forma inteligente: http://www.sindominio.net/ayuda/preguntas-inteligentes.html En espaol puedes encontrar tutoriales interesantes en http://macprogramadores.org/tutoriales/tutoriales/tutoriales.shtml. Para complementar este documento puedes leer:
El lenguaje Objective-C para programadores C++ y Java Programacin Cocoa con Foundation Framework

Hay varios libros buenos sobre desarrollo con Cocoa. Programming in Objective-C est orientado para principiantes. Algunos libros asumen que tienes al menos el conocimiento que puedes obtener de este libro. Hemos disfrutado con Cocoa Programming for Mac OS X de Aaron Hillegass of the Big Nerd Ranch y tambin Cocoa with Objective-C de James Duncan Davidson y Apple, publicado por O'Reilly. Finalmente unos consejos sobre precaucin. Ests programando para el Mac. Antes de liberar tu programa, asegrate no slo de que no tiene errores sino tambin de que tiene buen aspecto y se ajusta a las guas de interfaz humana de Apple (que estn descritas en este

16: Fuentes de informacin

Pgina 1 de 2

Become an Xcoder Espaol v1.15

vnculo). Una vez que lo hayas hecho, no seas tmido y haz tu programa disponible para todos. Los comentarios que te puedan hacer los dems te ayudarn a refinar y ampliar tu aplicacin y seguir manteniendo tu atencin en la calidad. Esperamos que hayas disfrutado este libro y contines programando con Xcode. Bert, Alex, Philippe.

16: Fuentes de informacin

Pgina 2 de 2

Become an Xcoder Espaol v1.15

Licencia
Este trabajo est bajo licencia Creative Commons Attribution 3.0.

Licencia

Pgina 1 de 1

You might also like