miércoles, 1 de junio de 2011

Breve descripción de métodos en Objective-C

Hola a todos!

En el siguiente post hablaremos un poco sobre los métodos en Objective-C. Sus tipos, función, sintaxis, y algún que otro ejemplo para comprenderlos mejor.


Actualizado 2-11-11 - Métodos de clase, ejemplos.


Les recuerdo que las definiciones de todo lo concerniente a programación son palabras en ingles, algunas se pueden traducir literalmente, otras no. Siempre es complicado saber cuando traducir algo, sobretodo porque a veces no tiene traducción. Pero la realidad es que es difícil comprender por completo el propósito o significado de algo si ni siquiera entiendes bien su nombre en tu idioma materno. Tratare de explicarme lo mejor posible para los casos que revisaré a continuación. Empecemos!

Expondré tres ejemplos sencillos de las method declarations o declaraciones de métodos. Esto, para los que son experimentados en C, se parecerá mucho a las function prototypes que no son mas que una declaración de las prestaciones que soporta dicho objeto.

En el archivo @interface es donde se colocan las declaraciones de métodos. Y como primer ejemplo tenemos:

- (void) imprime;

El guión nos dice que no es un function prototype (estos no llevan guión), luego viene entre paréntesis el tipo de datos que retorna el método, en este caso nada, Objective-C utiliza la palabra reservada void para indicar que no se retorna nada. Por último viene el nombre del método, en este caso "imprime".

Los métodos de Objective-C pueden retornar los mismos tipos que las funciones C: tipos estándar(int, float, y char), pointers (apuntadores), referencias a objetos y estructuras.

Un poco mas complicado tenemos:

- (void) setColor: (NSColor) Color;

Aquí el método setColor recibe un argumento del tipo NSColor. Este método hipotético lo que haría es cambiar el color a una variable de instancia.

Ahora analizamos todo por partes:

- (void)

El guión viene siendo la forma de decir al compilador "esto es un método que estamos declarando" y el void entre paréntesis es el tipo de retorno, como no creamos algo ni queremos informar al compilador de algo, entonces no devolvemos nada.

SetColor:

Luego del setColor, que es el nombre del método, tenemos el ":", esto es una ayuda para el compilador y para el programador que le informa que ahora vienen parámetros que utilizará el método para que haga lo que tenga que hacer.

(NSColor) Color;

Por ultimo el tipo de argumento entre paréntesis, en este caso NSColor. "Color" viene siendo el nombre del argumento que se utilizará dentro del cuerpo del método. Como siempre se recomienda usar nombres distintivos que ayuden a localizar rápida e intuitivamente los parámetros.

Podemos poner un ejemplo un poco mas complejo como el siguiente:

+ (id) stringWithFormat: (NSString *) format, ...;

El "+" lo hablamos mas adelante, el "id" dice que retorna algo no especificado, o sea puede retornar cualquier tipo de objeto: un NSString un NSArray etc. Pero prestemos atención a los puntos suspensivos al final. Esto le dice al compilador que el método puede recibir un numero no determinado de argumentos. Todos estos argumentos estarán separados por una coma, parecido al NSLog().


Notación INFIX

Objective-C permite la llamada notación INFIX, que quiere decir "arreglo interno". Dicha notación para los que vienen de Java o .Net puede ser algo complicada de comprender al principio. Pero esta notación una vez que la comprendes puedes ser muy útil para la lectura de métodos con múltiples argumentos. En ella puedes trazar con menor dificultad que argumento hace que.

Ejemplo: [circulo setColor: colorNegro]

aquí el método setColor ejecutado en el "circulo" recibe el argumento color "colorNegro".

Otro ejemplo [texto setString: @"Hola soy negro"
setColor: colorNegro]

El setString: y el setColor: son ambos los nombres de los argumentos en el nombre del método. Luego @"Hola soy negro" y "colorNegro" son los argumentos que se pasan a la función.


Tipos de métodos

Ahora nos metemos con métodos de clase, métodos de fábrica (factory methods) y métodos de instancias. Es fácil confundirlos, pero la clave esta en su sintaxis y lo que abarca dicho método.

Empezamos con un simple método de instancia:
- (BOOL) comparaString: (NSString) string1;

Este ya debe ser familiar, empieza con el guión, retorna un booleano y recibe como parámetro un NSString. Fácil, nada del otro mundo. Aquí sabemos que el método ejerce su función dentro del espectro de la instancia del objeto que lo llamó y nada más. Esto es un método de instancia.

Volviendo con el ejemplo anterior:

+ (id) stringWithFormat: (NSString *) format, ...;

Este método sería un método de clase, mas específicamente método de fábrica. Lo delata inicialmente su "+" al inicio. Pero para explicar esto primero debemos tener claro lo siguiente. Cuando Objective-C hace el build de la clase, genera un objeto que representa dicha clase. El objeto de clase contiene pointers que apuntan a la súperclase, el nombre de la clase, y una lista de los métodos de la clase. También posee un dato long, en bytes, que especifica el tamaño de las instancias de objetos creados recientemente.

Cuando se crea un método con el "+", se dice que ese método es del objeto clase (y no de la instancia del objeto) y típicamente es usado para crear nuevas instancias. Estos métodos no pueden acceder a las variables de instancia, porque? por que no son una instancia. Los métodos de clase tambien son utilizados para manipular data de acceso global. Por ejemplo tenemos el método redColor o blueColor de la clase NSColor del Application Kit. Este método se podría utilizar de la siguiente manera:

NSColor *azulon = [NSColor blueColor];

Otro ejemplo seria la clásica instanciación e inicialización de objetos. Por ejemplo:
ObjetoX * objX = [[ObjetoX alloc] init]  -> en este caso el metodo alloc crea el espacio para el objeto ObjetoX. En este ejemplo init NO es un método de clase ya que recibe una instancia para poder inicializar sus variables.

El método stringWithFormat: crea un nuevo objeto del tipo NSString con el formato especificado por el número de argumentos que se le den. En otras palabras si recibe 3 argumentos este objeto será distinto del que reciba 4 o 5 argumentos. En este caso no se esta creando una instancia de un objeto NSString, sino un objeto nuevo. Por ello es un factory method

En la gran mayoría de los casos se crearan métodos de instancia colocando el guión (-) adelante. Este ejercerá dentro del alcance de una instancia especifica. Para métodos con funciones más globales como instanciar objetos o acceder a data global, se declararán los métodos con el signo más (+).

Un ejemplo sobre instancias globales y su acceso mediante un método de clase seria el siguiente:

+ (ObjetoX) ObjetoPadre; -> este método retornaria la instancia del único objeto padre compartido (del cual todos derivan o el cual tiene el mayor rango dentro de una jerarquía especifica)

Espero esto haya sido de ayuda para aclarar algunas definiciones de Objective-C en cuanto a métodos se refiere.

2 comentarios:

  1. buena iniciativa chamo...nos podria servir un esquema de toda esta sintaxis!!. Necesito mucha información para entrar en la programación de IOS.

    Gracias por compartirlo

    Saludos

    ResponderEliminar
  2. Hola Omar. Documentación hay por montones, desde toda la que ofrece Apple en sus ebooks gratuitos, hasta los líbros de autores y programadores consagrados. Entre estos te puedo recomendar "Learn Objective C on the Mac" por Mark Dalrymple y Scott Knaster. Ellos exponen muy bien la sintaxis y demás teoría para principiantes en Objective C.

    Saludos

    ResponderEliminar