jueves, 15 de noviembre de 2012

¿Por qué utilizar una sentencia switch?


Para un número pequeño de evaluaciones lógicas con una estructura if ... else if ...  es perfectamente adecuado. Por desgracia, una estructura de este tipo con muchas preguntas resulta difícil de leer y darle mantenimiento. Como un ejemplo de ello consideremos siguiente ejemplo. El programa está diseñado para evaluar enteros entre 0 y 5 introducido por teclado:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
      NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

      int valor;

      printf ("Enter a number between 0 and 5: ");

      scanf ("%i", &valor);

      if (valor == 0)
        NSLog (@"cero");
      else if (valor == 1)
        NSLog (@"un simio");
      else if (valor == 2)
        NSLog (@"dos simios");
      else if (valor == 3)
        NSLog (@"tres simios");
      else if (valor == 4)
        NSLog (@"cuatro simios");
      else if (valor == 5)
        NSLog (@"cinco simios");
      else
        NSLog (@"Valor fuera de rango");

      [pool drain];
      return 0;
}

Como se puede ver, mientras que el código no es demasiado excesivo ya está empezando a ser un poco difícil de leer y también tomó más tiempo para escribir del que debería ser necesario.
Imaginemos, sin embargo, si en vez de cinco números que teníamos que probar más.
Es evidente que una solución más fácil es la sentencia switch.

Sintaxis de la sentencia switch

La sintaxis de la sentencia switch en Objective-C es la siguiente:

 switch (expresion)

 {
     case valor1:

          sentencias

          break;

     case valor2:

          sentencias

          break;

     default:

          sentencias

          break;

 } 


Con estra estructura evaluaremos la expresión en cada uno de sus resultados o "casos". Si el caso se cumple, se ejecutarán las sentencias hasta encontrarse el comando break. Si ningún caso de cumple, se ejecutarán las sentencias debajo de la palabra reservada default.


Ejemplo de una estructura condicional switch



Siguiendo el ejemplo de las sentencias if... else if, aplicaremos la sentencia switch:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   int valor;

   printf ("Introduce un número entre 0 y 5: ");

   scanf ("%i", &valor);

   switch (valor)
   {
      case 0:
        NSLog (@"No hay simios");
        break;
      case 1:
        NSLog (@"Un solitario simio");
        break;
      case 2:
        NSLog (@"Dos simios");
        break;
      case 3:
        NSLog (@"Tres simios");
        break;
      case 4:
        NSLog (@"Cuatro simios");
        break;
      case 5:
        NSLog (@"Cinco simios");
        break;
      default:
        NSLog (@"Número fuera de rango");
        break;
   }
        [pool drain];
        return 0;
}

Cuando el usuario teclea un número, la sentencia switch verifica si se encuentra en el rango y envía un mensaje correspondiente a la ventana de salida. Si el número, o lo que haya tecleado el usuario, no se encuentra en el rango, se ejecutará la sentencia debajo de default, indicando que el número se encuentra fuera de rango.

Combinando las intrucciones del case


Si queremos que se ejecuten varias sentencias al mismo tiempo, equivalentes a un OR en una estructura if, simplemente escribimos las sentencias case juntas, y se cumplirán todas las sentencias  hasta encontrarse con un break. En el siguiente caso se ejecutarán conjuntamente las opciones 0, 1 y 2:

   switch (valor)
   {
      case 0:
      case 1:
      case 2:
        NSLog (@"cero, uno o dos");
        break;
      case 3:
        NSLog (@"tres");
        break;
      case 4:
        NSLog (@"cuatro");
        break;
      case 5:
        NSLog (@"cinco, aqui te brinco");
        break;
      default:
        NSLog (@"Fuera de rango");
        break;
   }


miércoles, 14 de noviembre de 2012


Las sentencias condicionales

En el blog anterior vimos cómo usar las expresiones lógicas en Objective-C para determinar si algo es verdadero o falso.

Dado que la programación es en gran medida un ejercicio de aplicación de la lógica, gran parte de la técnica de la programación implica la escritura de código que toma decisiones sobre la base de uno o más criterios.

Tales decisiones definir qué código se ejecuta y, a la inversa, que recibe el código anulado cuando el programa se está ejecutando.

Esto se refiere a menudo como control de flujo, ya que controla el flujo de la ejecución del programa.

En los capítulos anteriores, la declaración si se ha utilizado en algunos ejemplos. En este capítulo de Fundamentos de Objective-C 2.0, vamos a ver si las declaraciones de un poco más de detalle.


Uso de la instrucción if

La sintaxis básica del la declaración en Objective-C es el siguiente: La sentencia if es tal vez la más básica de las opciones de control de flujo disponibles.

Los programadores que estén familiarizados con C, C + + o Java inmediatamente se sentirán cómodos usando el if.

if (expresión booleana) {
    / / Objective-C código que se lleva a cabo cuando la expresión se evalúa como verdadera
}

Tenga en cuenta que las llaves ({}) sólo son necesarias si hay más de una línea de código que se ejecuta después de que la expresión if.

Si sólo hay una línea de código aparece en el caso de las llaves son opcionales.

Por ejemplo, el código válido lo siguiente:



int x = 10;

if (x > 10)
       x = 10;

En esencia, si la expresión booleana se evalúa como 1 (verdadero), entonces el código en el cuerpo de la sentencia se ejecuta. 

El cuerpo de la declaración se encierra entre llaves ({}). 

Si, por otro lado, la expresión se evalúa a 0 (falso) el código en el cuerpo de la instrucción se salta.

Por ejemplo, si una decisión debe hacerse en función de si un valor es mayor que otro, sería escribir código similar al siguiente:


int x = 10;

if ( x > 9 )
{
         NSLog (@"x es mayor que 9!");
}

Claramente, x es de hecho mayor que 9 haciendo que el mensaje que aparezca en la ventana de la consola.

Usando la declaración if ... else ..


La siguiente variación de la sentencia if nos permite especificar también algo de código a ejecutar si la expresión en la sentencia if se evalúa como false. La sintaxis de esta construcción es como sigue:

if (expresión booleana) {
      / / Código que se ejecuta si la expresión es verdadera
} else {
     / / Código que se ejecuta si la expresión es falsa
}

Uso de la sintaxis anterior, ahora podemos extender nuestro ejemplo anterior para mostrar un mensaje diferente si la expresión de comparación se evalúa como falsa:


int x = 10;

if ( x > 9 )
{
         NSLog (@"x es mayor que 9!");
}
else
{
         NSLog (@"x es menor que 9!");
}


En este caso, la instrucción NSLog segundo ejecutaría si el valor de x era menor que 9.
Usando if ... else if .. Declaraciones

Hasta ahora hemos examinado si las declaraciones que hagan decisiones basadas en el resultado de una expresión lógica única. 

Algunas veces es necesario para tomar decisiones sobre la base de un número de criterios diferentes. 

Para ello podemos utilizar el if ... else if ... construir, la sintaxis de la cual es como sigue:


int x = 9;

if (x == 10)
{
       NSLog (@"x is 10");
}
else if (x == 9)
{
       NSLog (@"x is 9");
}
else if (x == 8)
{
       NSLog (@"x is 8");
}

Este enfoque funciona bien para un número moderado de las comparaciones, pero puede llegar a ser engorroso para un volumen más grande de las evaluaciones de expresión. 
Para tales situaciones, la declaración de Objective-C switch ofrece una solución más flexible y eficiente. Para obtener más información sobre el uso de la sentencia switch leer el capítulo titulado 
El interruptor de Objective-C



viernes, 9 de noviembre de 2012

Precedencia en Objective-C

Cuando los seres humanos evaluamos expresiones, por lo general lo hacemos de la izquierda hacia la derecha. Por ejemplo, trabajando de izquierda a derecha se obtiene un resultado de 300 a partir de la siguiente expresión:
 
10 + 20 * 10 = 300

Esto se debe a que nosotros, como seres humanos, sumamos 10 a 20, dando  30 y luego multiplicar por 10 para llegar a 300. Si Objective-C realizara el mismo cálculo y se obtiene un resultado muy diferente:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

        int x = 10 + 20 * 10;

        NSLog(@"El resultado es %i", x);
        [pool drain];
        return 0;
}
Cuando se ejecuta, el resultado del cálculo se asigna a la variable x enteros y, posteriormente, se muestra utilizando la llamada NSLog:
El resultado es 210
Como podemos ver en la salida anterior, Objective-C considera que la respuesta es 210.
Este es un resultado directo de la prioridad de los operadores. Objective-C tiene un conjunto de reglas que le indican el orden en el que los operadores deben ser evaluados en una expresión.

Objective-C considera el operador de multiplicación (*) tiene una mayor precedencia que la suma (+).

Al abordar la cuestión de la precedencia de los operadores en algunos lenguajes de scripting y programación, lo único que se requiere es generalmente una tabla con los operadores en orden de prioridad de mayor a menor. 
Objective-C tiene más en común con lenguajes como Java y C # en que los operadores estén agrupados en diferentes niveles de precedencia.  
Cuando los operadores del mismo nivel de prioridad se encuentran dentro del contexto de una sola expresión, se sigue una regla en cuanto al orden en el que los operadores han de evaluarse. 
Esta regla se conoce como la asociatividad y difiere de un grupo a otro.  
En la tabla siguiente se describen los grupos de operadores de precedencia y asociatividad correspondiente para Objective-C:

Como podemos ver en la tabla, cuando los operadores del mismo nivel de precedencia aparezcan en una expresión, los operadores se evalúan ya sea de izquierda a derecha o de derecha a izquierda según la asociatividad de ese grupo.  

Por ejemplo, la siguiente expresión se evalúan de izquierda a derecha, debido tanto a los operadores están en el mismo nivel de prioridad y esta es la regla dictados por la asociatividad correspondiente:
 
OperadorDescripciónPrecedenciaAsociatividad
[]
.
()
->
acceso a un elemento array o a una expresión
acceso a un método o propiedad
invoca a un método o propiedad
aputador aun miembro de una estructura
La más altade izquierda a derecha
++
--
+
-
!
~
*
&
sizeof
(type)
incremento
decremento
unary plus
negativo
NOT lógico
complemento
apuntador
dirección
tamaño del objeto
cambio de tipo (cast)
derecha a izquierda
*
/
%
multiplicación
división
módulo
de izquierda a derecha
+
-
suma
resta
de izquierda a derecha




<=
>=
>
menor o igual
mayor o igual
mayor que
de izquierda a derecha
==
!=
igualdad
de izquierda a derecha












&&ANDde izquierda a derecha
||ORde izquierda a derecha
?:if condicionalderecha a izquierda
  =   +=   -=
 *=   /=   %=
 &=   ^=   |=
<<=  >>= >>>=
asignación
derecha a izquierda
,
coma
menorderecha a izquierda
int x = 10 * 20 / 5;

Modificar la precedencia

Las reglas de precedencia y asociatividad integrados en Objective-C puede ser modificados por los paréntesis. Por ejemplo, se puede anular la precedencia y forzar a la izquierda a la derecha evaluación de nuestro ejemplo original de la siguiente manera:
int x = (10 + 20) * 10;

NSLog(@"El resultado es   %i", x);

En el ejemplo anterior, el fragmento de expresión entre paréntesis se evalúan antes de la más alta prioridad multiplicación resulta en la expresión equivalente a 300 en lugar de 210 , cuando no modificamos la precedencia original de Objective-C:
El resultado es 300




jueves, 8 de noviembre de 2012

Operadores y expresiones en Objective-C

  • En los capítulos anteriores se observó el uso de variables y constantes en Objective-C y también se describen los diferentes tipos de datos. 
  • Crear variables es sólo parte de la historia. 
  • El siguiente paso es aprender cómo utilizar estas variables y constantes en el código de Objective-C
  • El método principal para trabajar con datos es en forma de expresiones. 
  • En este capítulo vamos a analizar en detalle las expresiones de Objective-C y los operadores.

¿Qué diablos es una expresión?

La expresión más básica consiste en que un operador, operando dos y una asignación. El siguiente es un ejemplo de una expresión:

int resultado = 1 + 2;
En el ejemplo anterior, el operador (+) se utiliza para añadir dos operandos (1 y 2) juntos. 
El operador de asignación (=) posteriormente "mete" el resultado de la suma a una variable entera llamada resultado. 
Los operandos pueden ser variables, constantes, literales o expresiones (o una mezcla de constantes y variables).

Veamos los distintos tipos de operadores disponibles en Objective-C.


El operador de asignación


Ya hemos visto en el más básico de los operadores de asignación, el operador =. 
 El operador de asignación simplemente asigna (o "mete") el resultado de una expresión a una variable. 
En esencia, el operador de asignación = toma dos operandos. 
El operando de la izquierda es la variable a un valor que se va a asignar y el operando de la derecha es el valor que se asignará.  
El operando de la derecha es, más a menudo, una expresión que realiza algún tipo de operación aritmética o de evaluación lógica , el resultado de que se asigna a la variable.  
Los siguientes ejemplos son válidos todos los usos del operador de asignación:
int x; // declaramos la variables

x = 10;  // Asignamos el valor de 10

x = y + z; //Asignamos la suma de z y y a la variable
x = y;   // Asignamos el valor de y a la variable
Los operadores de asignación también puede ser" encadenados" a asignar el mismo valor a múltiples variables.  
Por ejemplo, el ejemplo de código siguiente asigna a las variables el valor 20 a la x, y y z:

int x, y, z;

x = y = z = 20;

Operadores aritméticos en Objective-C

Objective-C ofrece una amplia gama de operadores con el fin de crear expresiones matemáticas.  
Estos operadores principalmente caen en la categoría de operadores binarios en los que se toman dos operandos. 

La excepción es el operador unario negativo (-) que sirve para indicar que un valor es negativo o positivo.
Este operador es diferente al operador de resta (-) que toma dos operandos (es decir, un valor que se resta de otro).  
Por ejemplo:

int x = -10; // Operador unario

x = y - z; // Resta de dos variables
Los operadores matemáticos son los siguientes:

OperadorDescripción
-(unario)Cambia a valor negativo una variable o expresión
*Multiplicación
/División
+Suma o adición
-Resta o sustracción
%Módulo

En una expresión, podemos utilizar muchos operadores matemáticos, por ejemplo:

x = y * 10 + z - 5 / 4;

Mientras que el código anterior es perfectamente válido, es importante tener en cuenta que Objective-C NO evalúa la expresión de izquierda a derecha o de derecha a izquierda, sino más bien en un orden especificado por la precedencia de los distintos operadores. 


Operadores abreviados


En una sección anterior vimos que el operador básico de asignación (=).  
Objective-C proporciona un número de operadores diseñadas para combinar un trabajo con una operación matemática o lógica. 
 Estos son principalmente de uso al realizar una evaluación donde el resultado es que se almacena en uno de los operandos.  
Por ejemplo, se podría escribir una expresión como sigue:
x = x + y;

La expresión anterior se suma el valor contenido en la variable x para el valor contenido en la variable y y almacena el resultado en la variable x
Esto lo podemos simplificar de la siguiente forma:
x += y



La expresión anterior realiza exactamente la misma tarea que x = x + y, pero evita al programador algo de tecleo.

Los operadores abreviados que se encuentran disponibles en Objective-C se resumen en la siguiente tabla:

OperadorEquivale a:
x += y
x = x + y;
x -= y
x = x - y;
x *= y
x = x * y;
x /= y
x = x / y;
x %= y
x = x % y;

Operadores para incrementar y decrementar


Otro atajo útil se puede lograr utilizando el incremento Objective-C y los operadores de decremento (también referido como operadores unarios porque operan en un único operando).  
Al igual que con los operadores de asignación abreviados descritos en la sección anterior, considere lo siguiente  fragmento de código:
x = x + 1; // Incrementa el valor de x en uno

x = x - 1; // Decrementa el valor de x en uno

Estas expresiones aumentar y disminuir el valor de x en 1.  
En lugar de utilizar este método es más rápido usar los operadores + + y --. L
os siguientes ejemplos realizar exactamente las mismas tareas que los ejemplos anteriores:

x++; Incrementa el valor de x en uno


x--; Decrementa el valor de x en uno
Estos operadores se pueden colocar antes o después del nombre de variable.  
Si el operador se coloca antes del nombre de la variable de incremento o decremento se realiza antes que cualquier otras operaciones se realizan en la variable.  
Por ejemplo, en el siguiente ejemplo, x se incrementa antes de que se asigna a y, dejando a y con un valor de 10:

int x = 9;
int y;

y = ++x;

En el ejemplo siguiente, sin embargo, el valor de x (9) está asignado a la variable y el valor de reducción antes de que se realiza.  
Después de la expresión se evalúa el valor de y será 9 y el valor de x será 8.
int x = 9;
int y;

y = x--;

Operadores de comparación

Además de los operadores matemáticos y asignación, Objective-C también incluye un juego de operadores lógicos útiles para realizar comparaciones.  
Estos operadores devuelven un booleano (BOOL) true (1) o falso (0) en función del resultado de la comparación.

Los operadores de comparación son los más usados ​​en la construcción de flujo del programa de control lógico

 Por ejemplo, una sentencia if se puede construir en base a si un valor coincide con otro:

if (x == y)
      
El resultado de la comparación también puede ser almacenado en una variable BOOL. Por ejemplo, el siguiente código se traducirá en un verdadero (1) valor que se almacena en la variable de resultado:
BOOL result;
int x = 10;
int y = 20;

result = x < y;

Es evidente que 10 es menor que 20, lo que resulta en una verdadera evaluación de laexpresión  x < y . 
La siguiente tabla muestra el conjunto completo de operadores de comparación de Objective-C:

OperadorDescripción
x == yRegresa verdadero si x es igual a y
x > yRegresa verdadero si x es mayor que y
x >= yRegresa verdadero si x es mayor o igual que y
x < yRegresa verdadero si x es menor que y
x <= yRegresa verdadero si x es menor o igual que y
x != yRegresa verdadero si x es diferente que y

Operadores lógicos


Objective-C también proporciona un conjunto de operadores conocidos como los operadores lógicos diseñados para devolver true (YES) y false (NO).  
En la práctica equivale a un verdadero (1) y  falso es igual a 0. Estos operadores tanto devuelven resultados booleanos y toman valores booleanos como operandos
Los operadores principales no son, AND (&&), OR (!) (| |) Y XOR (^).

El
Operador  NOT (!) simplemente invierte el valor actual de una variable booleana, o el resultado de una expresión.  

Por ejemplo, si un indicador variable llamada actual 1 (verdadero), anteponiendo la variable con un operador '!'  invierte el valor a 0 (falso):

bool bandera= YES; //variable verdadera
bool bandera2;
bandera2 = !bandera; // La segunda variable es falsa
El OR (| |) devuelve 1 si uno de sus dos operandos se evalúa como verdadera, de lo contrario, devuelve 0. Por ejemplo, el ejemplo siguiente se considera verdadero, porque al menos una de las expresiones de cada lado del operador OR es verdadera:
 if ((10 < 20) || (20 < 10))
        NSLog (@"Es verdadeo!!!!");

El operador AND (&&) regresa un valor 1 o verdadero, sólo si ambas expresiones son verdaderas.
La siguiente expresión regresa un valor falso pore una de las expresiones es falsa:

if ((10 < 20) && (20 < 10))
      NSLog (@"mmmmm...");

El operador ternario

Objective-C utiliza algo llamado un operador ternario para proporcionar una forma de acceso directo de la toma de decisiones.  
La sintaxis del operador ternario (también conocido como el operador condicional) es como sigue:

[condición] ? [expresión si el resultado es verdadero] : [expresión si el resultado es falsa]

La forma en que esto funciona es que [condición] se reemplaza con una expresión que se va a devolver. Verdadero (1) o falso (0) Si el resultado es verdadero, entonces la expresión que sustituye a la [verdadera expresión] se evalúa. Por el contrario, si el resultado es falso entonces el [expresión falsa] se evalúa.  
Vamos a ver esto en acción:
int x = 10;
int y = 20;

NSLog(@"El número mayor es %i", x > y ? x : y );

miércoles, 7 de noviembre de 2012

Variables y constantes en Objetive-C

El manejo de variables y constantes en Objective-C es fundamental para crear cualquier aplicación. Una variable es como una pequeña cajita donde podemos almacenar y recuperar cosas (datos).

¿Qué es una variable en Objective-C?

  • Las variables son esencialmente ubicaciones en la memoria de la computadora que están reservadas para el almacenamiento de los datos utilizados por una aplicación.
  • A cada variable se le asigna un nombre por el programador y le asigna un valor.
  • El nombre asignado a la variable se puede utilizar en el código de Objective-C para acceder al valor asignado a la variable. 
  • Este acceso puede implicar o bien la lectura del valor de la variable, o cambiar el valor. 
  • Es, por supuesto, la capacidad de cambiar el valor de las variables que les da el nombre de la variable.
Una variable debe ser declarada como un tipo particular, como un int, un char, un float o double.

Objective-C es lo que se conoce como un lenguaje "fuertemente tipado" (si, ya se, "tipado" no existe en Español) en que una vez que una variable ha sido declarada como un tipo particular, posteriormente no se puede cambiar a un tipo diferente.

Si bien esto puede resultar un poco extraño para quienes están familiarizados con los lenguajes "débilmente tipados" como Ruby, le serán familiares para programadores que vengan de Java, C, C + + o C#.  

Sin embargo, podemos cambiar el contenido por medio de la "conversión de tipos".

Una declaración de variables, entonces, necesita primero un tipo de datos, luego el nombre de la variable y opcionalmente podemos asignarle un valor de inicio.

int tasaDeInteres;

El siguiente ejemplo declaramos e iniciamos al mismo tiempo a la misma variable. El símbolo de igualdad (=) es un operdor de asignación:

int tasaDeInteres = 10;

De la misma forma podemos asignar un valor a la variable en cualquier punto del programa.

double tasaDeInteres = 5.5456; 

tasaDeInteres = 10.98; 

tasaDeInteres = 20.87; 


¿Qué es una constante en Objective-C?


Las constantes son particularmente útiles si hay un valor que se utiliza repetidamente en todo el código de la aplicación.

En lugar de usar el valor cada vez, hace que el código sea más fácil de leer si el valor se asigna por primera vez a una constante que a continuación se hace referencia en el código.

Por ejemplo, puede que no sea evidente para alguien que está leyendo su código de Objective-C por qué ha utilizado el valor 5 en una expresión.

Si, en lugar del valor 5, se utiliza una constante denominada tasaDeInteres el propósito del valor se vuelve mucho más claro.

Las constantes también tienen la ventaja de que si el programador necesita cambiar un valor ampliamente utilizado sólo necesita ser cambiado una vez en la declaración de la constante y no cada vez que la constante es referenciada.

Las constantes son similares a una variable en que se proporciona una ubicación memoria para almacenar  datos.

Las constantes difieren de una manera significativa en que una vez que se ha asignado un valor a una de ellas, posteriormente no se puede cambiar.

Al igual que las variables, las constantes tienen un tipo de datos, un nombre de constante y un valor.

A diferencia de las variables, una constante necesita que le asignemos un valor al ser creada, de lo contrario el compilador nos marcaría un error.

const int tasaDeInteres = 10;

Una vez que asignamos el valor a una constante, no podemos cambiarlo (de ahí su nombre).

const int tasaDeInteres = 10;
tasaDeInteres = 5; 

Cambiar el tipo de datos de una variable


Como semencionó anteriormente, el lenguaje Objective-C es "fuertemente tipado" (si, ya se, no existe esa palabra).

En cristiano, significa que una vez que le asignas un tipo de datos a una variable, este tipo NO PUEDE SER MODIFICADO.

A la operación  de cambiar el tipo de datos le llamamos "casting", o en otra palabra que NO existe en español, "casteamos" la variable (término que se originó en Java, según cuentan la leyenda).

Un ejemplo de conversión de datos es el siguiente:

double balance = 100.54;
double tasaDeInteres = 5.78;
double resultado = 0;
 
resultado = balance * tasaDeInteres;
  
NSLog(@"El resultado es %f", tasaDeInteres);

El resultado sería el siguiente:

El resultado es 581.121200

Si deseáramos cambiar el tipo de datos (del resultado) utilizaremos un conversor de tipos, en este caso para un número entero:

double balance = 100.54;
double tasaDeInteres = 5.78;
double resultado;
 
resultado =  (int) balance *  (int) tasaDeInteres;
  
NSLog(@"El resultado es %f", resultado);

El resultado sería:
El resultado es 500.000000

Note que lo que cambia es la representación de los datos, no el tipo de datos de la variable.

martes, 6 de noviembre de 2012

Tipos de datos en Objective-C

Los siguientes tipos de datos se consideran variables primitivas en Objective-C. Tienen la propiedad que su almacenamientos es fijo. En este lenguaje, como podrá observar, las cadenas NO se consideran un tipo de dato primitivo, sino un objeto.

int

El tipo de de datos Objective-C  int puede almacenar un número entero positivo o negativo (es decir, un número sin decimales).
El tamaño real o el rango de número entero que puede ser manejado por el tipo de datos int depende  del compilador.
Normalmente, la cantidad de almacenamiento asignado a valores int es de 32-bit o 64-bit dependiendo de la implementación de Objective-C en esa plataforma o la CPU en la que el compilador está ejecutándose.
Es importante señalar, sin embargo, que el sistema operativo también juega un papel en si los valores int son 32 o 64 bits.
Por ejemplo la CPU en una computadora puede ser de 64 bits, pero el sistema operativo que se ejecuta en el mismo sólo puede ser de 32 bits.


Por ejemplo, en una aplicación de 32-bit, el rango máximo de un entero sin signo es de 0 a 4294967295.
En un sistema de 64-bit de este rango sería 0 a 18.446.744.073.709.551.615.
Cuando se trate de valores int con signo (negativos y positivos), los rangos son -2147483648 hasta 2147483647 y -9.223.372.036.854.775.808 a +9.223.372.036.854.775.807 para las implementaciones de 32 bits y 64 bits, respectivamente.
Al escribir un programa Objective-C, la única garantía que tenemos es que un int será por lo menos de 32-bits de ancho.
Para evitar futuros problemas al compilar, el código en otras plataformas es más seguro para limitar valores int para el rango de 32-bit, en lugar de asumir que el 64-bit estará disponible.
De forma predeterminada, los valores int son decimales (es decir, basados ​​en la base número 10).
Para expresar un entero en octal (base número 8) simplemente preceder el número con un cero (0). Por ejemplo:

int miOctal = 024;

De manera similar, un int puede ser expresado en la base 16 (hexadecimal) precediendo el número con 0x, por ejemplo:


int miHex = 0xFFA2;

char

El Objective-C tipo de datos char se utiliza para almacenar un solo carácter, como una letra, número o signo de puntuacion numérico o carácter de espacio.
Por ejemplo, las siguientes líneas asignan una variedad de caracteres  diferentes para las variables de tipo char:

char miChar = 'w';
char miChar = '2';
char miChar = ':';


Caracteres especiales / Secuencias de Escape

Además del conjunto estándar de caracteres descritos anteriormente, también hay una serie de caracteres especiales (también conocido como escapar secuencias) disponible para los artículos que especifican como una nueva línea o un tabulador.
Estos caracteres especiales se identifican anteponiendo el carácter con una barra invertida (un concepto conocido como "escape").
Por ejemplo, el siguiente se asigna una nueva línea a la variable llamada nueva línea:

caracteres de nueva línea = '\ n';

En esencia, cualquier carácter que está precedido por una barra invertida se considera que es un carácter especial y es tratado com o tal por el compilador. Esto plantea la cuestión de saber qué hacer si usted quiere realmente un carácter de barra invertida. Esto se consigue por escapar de la propia barra inversa:

char miBarra = '\\';




Los caracteres especiales soportados por Objective-C son los siguientes:

\ A - El sonido de alerta
\ b - Retroceso
f \ - Avance de página
\ n - Nueva línea
\ r - Retorno de carro
\ t - Tabulador horizontal
\ v - Tabulador vertical
\ \ - Backslash
\ "- Doble comilla (usado cuando se hace una cita doble en una declaración cadena)
\ '- Comilla simple (se utiliza cuando se hace una cita doble en una declaración cadena)



float


El tipo de datos float de Objective-C se utiliza para almacenar los valores de punto flotante, en otras palabras que contengan valores decimales.
Por ejemplo, 456.12 sería almacenado en un tipo de datos float.
En la práctica, todos los valores de coma flotante se almacenan como un tipo de datos diferente (llamado doble) de forma predeterminada.
Vamos a estar cubriendo el tipo de datos double siguiente, pero si usted desea específicamente para utilizar un tipo de datos float, debe anexar una f al final del valor. Por ejemplo:

float miFloar = 123.432f;

Para una mayor comodidad cuando se trabaja con un número excepcionalmente grande de datos, tanto de punto flotante y doble escriba valores pueden ser especificados en notación científica (también conocida como notación exponencial).
Por ejemplo, podemos expresar 67.7 x 104 en Objective-C como:

float miFloat = 67.7e4


double

El tipo de datos double de Objective-C se utiliza para almacenar los valores más grandes que pueden ser manejados por el tipo de datos float.
El término "double" viene del hecho de que un double puede manejar valores de dos veces el tamaño de un float.
Como se mencionó anteriormente, todos los valores de coma flotante se almacenan como tipos de datos dobles a menos que el valor es seguido por un 'f' para especificar específicamente un float en lugar de como un double.

id

En Objective-C gran parte de la forma en que se estructuró un programa está en la forma de los objetos reutilizables.
Estos objetos son llamados a realizar tareas y devolver resultados.
A menudo, la información que se pasa en un objeto y los resultados devueltos serán en la forma de otro objeto.
El tipo de datos id es de propósito general, y se puede utilizar para almacenar una referencia a cualquier objeto, independientemente de su tipo.

BOOL

Objective-C, al igual que otros idiomas, incluye un tipo de datos para manejar resultados verdaderos o falsos (1 o 0).
Este tipo de datos se declaran usando cualquiera de las palabras clave o _Bool BOOL.
Ambas expresiones siguientes son válidas:

_Bool flag = 0;
BOOL secondflag = 1;

En Objetive-C no tenemos las contantes true y false, como en otros lenguajes que provienen del C. En cambio tendremos las contantes YES y NO, respectivamente.

Los calificadores de datos en Objective-C 

Hasta ahora hemos visto los tipos de datos básicos en el contexto del lenguaje de programación Objective-C.
Hemos visto que los tipos de datos son seleccionados dependiendo del datos que deseemos almacenar y del espacio en memoria que deseemos utilizar.
Cada tipo de datos está asociada con algunas restricciones en cuanto a qué tipo de datos puede contener.
De hecho, es posible modificar algunas de estas limitaciones mediante el uso de los calificadores.
Los siguientes calificativos modifican las restricciones de almacenamiento de los tipos de datos que vimos en la parte superior.

long


El calificador long se utiliza para extender el rango de valores de un tipo de datos.
Por ejemplo, para aumentar el alcance de una variable entera, la declaración es prefijado por el calificador:

long int miEnteroLargo;

La cantidad en que se incrementa rango un tipo de datos a través del uso del calificador long depende del sistema operativo, aunque en muchos sistemas modernos int y long tienen el mismo rango, haciendo innecesario el uso del calificador.
El calificador de long también se puede aplicar al tipo de datos double.
Por ejemplo:

long double miDobleLargo;


long long

Los calificadores long long equivalen a extra long.
En el caso de un tipo de datos int, el calificador long long cambia un entero de 32-bit a 64-bit:

long long int miEnteroLargo;

short

El calificador short se puede utilizar para reducir el espacio de almacenamiento y el rango del tipo de datos int.
Esto reduce el número entero a 16-bits de ancho, lo que limita el rango de valores con signo de -32.768 a 32.767:

short int miEnteroCorto;

signed / unsigned

De forma predeterminada, un número entero se supone que contiene el signo, es decir, puede almacenar positivos y negativos.
Esto limita la medida en que el rango puede alcanzar en cualquier dirección.
Por ejemplo, un int 32-bit tiene una gama de 4.294.967.295.
En la práctica, debido a que el valor puede ser positivo o negativo de la gama es en realidad desde -2147483648 hasta 2147483647.
Si sabemos que una variable no serán utilizada para almacenar un valor negativo, podemos declarar como no firmado, ampliando así el rango (positivo) para desde 0 hasta 4294967295.
Un entero sin signo se especifica de la siguiente manera:

unsigned int myint;

Los modificadores pueden ser combinados:

unsigned short int miEntero = 10;

Si usamos los  calificadores unsigned, signed, short y long con el typo de datos entero, La palabra reservada int es opcional. Las siguientes sentencias serían válidas:

short miInt;
long miInt;
unsigned miInt;
signed miInt;

lunes, 5 de noviembre de 2012

Manejo de archivos


Manejo de archivos en Objective-C

Uno de los temas mas importantes para hacer aplicaciones robustas con Objective-C es el manejo de archivos. En el blog anterior se vió cómo manejar los directorios con la clase NSFileManager y las clases NSFileHandle and NSData dentro del Framework-Foundation.
Ahora veremos el apasionante tema de crear, manejar y eliminar datos.
 

El directorio por referencia

  1. Primero debemos de obtener el directorio de la aplicación, la cual por lo general la conocemos como "home", "root" o "raiz". 
  2. Esta referencia raìz la obtenemos con el método defaultManager de la clase NSFileManager, creando una instancia de la misma:

NSFileManager *raiz;
raiz= [NSFileManager defaultManager];

Verificar si existe un archivo

  1. La clase NSFileManager contiene un método llamado fileExistsAtPath el cual verifica la existencia de un archivo. 
  2. El método toma como argumento una cadena NSString y regresará un valor booleano verdadero (YES) si el archivo existe o un valor negativo (NO) de lo contrario:

NSFileManager *raiz;

raiz = [NSFileManager defaultManager];

if ([raiz fileExistsAtPath: @"/tmp/myfile.txt" ] == YES)
        NSLog (@"Si existe el archivo");
else
        NSLog (@"Archivo no encontrado");

Comparación de dos archivos

Podemos comparar el contenido de dos archivos por medio del método contentsEqualAtPath. Este método toma como argumentos al nombre y el directorio de los dos archivos. Regresaa un valor falso (NO) si es que son diferentes y un verdadero (YES) si los contenidos son iguales:

NSFileManager *raiz;

raiz= [NSFileManager defaultManager];

if ([raiz contentsEqualAtPath: @"/tmp/compras.txt" andPath: @"/tmp/ventas.txt"] == YES)
        NSLog (@"Los contenidos son iguales");
else
        NSLog (@"Los contenidos son diferentes");

Verificando los permisos del archivo

La mayorìa de los sistemas operativos (de servidores, locales o de dispositivos móviles) asignan "permisos" a cada archivo y directorio. Por medio de los siguientes métodos podemos saber si se cuenta con el permiso respectivo: isReadableFileAtPath, isWritableFileAtPath, isExecutableFileAtPath y isDeletableFileAtPath. Cada uno regresa un valor booleano verdadero (YES) si el archivo tiene ese permiso o un falso (NO) si no lo tiene

NSFileManager *raiz;

raiz = [NSFileManager defaultManager];

if ([raiz isWritableFileAtPath: @"/tmp/myfile.txt"]  == YES)
        NSLog (@"El archivo tiene permiso para ser escrito");
else
        NSLog (@"El archivo es sólo lectura");

Mover o renombrar un archivo

 Un archivo puede ser renombrado, en caso que tenga ese permiso, usando el método moveItemAtURL. Este método regresará un valor booleano verdadero (YES) si la acción de renombrar fue exitosa y uno falso (NO) de lo contrario. Se tiene un objeto de tipo error NSError, el cual devuelve un valor nil si la operación fue exitosa, y un objeto de error si la operación de renombrar falló:

NSFileManager *raiz;

raiz = [NSFileManager defaultManager];

NSURL *dirAct = [NSURL fileURLWithPath:@"/tmp/archivoActual.txt"];
NSURL *dirNuevo= [NSURL fileURLWithPath:@"/tmp/archivoNuevo.txt"];

[raiz moveItemAtURL: dirAct toURL: dirNuevo error: nil];

Copiar un archivo

Por medio del método copyItemAtPath es posible copiar un archivo. Los argumentos y valores de respuesta son los mismos que en el proceso de renombrar el archivo que se vieron en el segmento anterior.

NSFileManager *raiz;

raiz= [NSFileManager defaultManager];

if ([raiz copyItemAtPath: @"/tmp/archivoActual.txt" toPath: @"/Users/demo/archivoNuevo.txt" error: NULL]  == YES)
        NSLog (@"Copia exitosa");
else
        NSLog (@"Error en la copia");


Borrar un archivo

El método removeItemAtPath permite borrar o remover un archivo. El método toma el ombre de archivo con su camino (opcional) y un objeto de la clase NSError. Regresa un valor booleano en respuesta a la operación, indicando si la misma fue exitosa (YES) o no (NO).

NSFileManager *raiz;

raiz = [NSFileManager defaultManager];

if ([raiz removeItemAtPath: @"/tmp/miArchivo.txt" error: NULL]  == YES)
        NSLog (@"Borrado exitoso");
else
        NSLog (@"Error al borrar");

Crear un link simbólico

Podemos crear un link simbólico a un archivo por medio del método createSymbolicLinkAtPath. Los argumentos de este mètodo son el camino que deseamos volver link simbòlico, el nombre del archivo y un objeto de la clse NSError, que regresa algùn valor si la operaciòn no fue satisfactoria.

NSFileManager *raiz;

raiz = [NSFileManager defaultManager];

if ([raiz createSymbolicLinkAtPath: @"/tmp/archivo2.txt"
                withDestinationPath: @"/tmp/archivo.txt" error: nil] == YES)
        NSLog (@"Ligado exitoso");
else
        NSLog (@"Error al crear el link");

Leer y escribir archivos con NSFileManager

Una forma muy básica y limitada de leer y escribir archivos es por medio de la clase NSFileManager.
El contenido que se va a grabar debe de estar contenido en un objeto de tipo NSData antes de utilizar el método contentsAtPath:

NSFileManager *raiz;
NSData *databuffer;

raiz = [NSFileManager defaultManager];

databuffer = [raiz contentsAtPath: @"/tmp/archivo.txt" ];

Una vez que los datos están almacenados en el objeto NSData, podemos utilizar el método createFileAtPath para escribir el archivo:

databuffer = [raiz contentsAtPath: @"/tmp/archivo.txt" ];

[raiz createFileAtPath: @"/tmp/ArchivoNuevo.txt" contents: databuffer attributes: nil];




Esta forma de crear un archivo no nos permite saber cuánta informaciçon se copió ni hacer una operación de append al final del mimso.i el archivo destino ya exste, se sobreescribe perdiendo los datos anteriores. Una forma mucho màs robusta de grabar información es por medio de la clase NSFileHandle perteneciente al Framework-Fundation.

Uso de la clase NSFileHandle para la operación con archivos

The NSFileHandle class provides a range of methods designed to provide a more advanced mechanism for working with files. In addition to files, this class can also be used for working with devices and network sockets. In the following sections we will look at some of the more common uses for this class.

Crear un objeto NSFileHandle

Un objeto NSFileHandle al abrir un archivo para leer, escribir o añadir datos al final del mismo. Para ello se pueden utilizar, respectivamente, los siguientes métodos:
  • fileHandleForReadingAtPath
  • fileHandleForWritingAtPath
  •  fileHandleForUpdatingAtPath 

Una vez efectuado su operación, se deberà cerrar con el método closeFile. Si el proceso de apertura del archivo falla, el mètodo regresará un valor de nil.
NSFileHandle *archivo;

archivo = [NSFileHandle fileHandleForWritingAtPath: @"/tmp/archivo.txt"];

if (archivo == nil)
        NSLog(@"Error al abrir el archivo");

[archivo closeFile];

El proceso de desplazamiento (Offsets) y búsqueda (Seeking)

  1. Un objeto de la clase NSFileHandle mantiene un apuntador para marcar la posición actual del archivo. 
  2. Esta posición se le conoce como offset, o el desplazamiento del apuntador con respecto al inicio del archivo. 
  3. Cuando el archivo es abierto, este apuntador se encuentra al inicio del mismo y su valor es cero (0).
  4. Esto quiere decir que cualquier operacon iniciará cvon un valor del apuntador de cero.
  5. Para efectuar una operación en otra parte del archivo, digamos al final, necesitamos primero buscar (seek) ese desplazamiento (offset).
  6. Por ejemplo, si desea mover el apuntador al final del archivo, puede hacerlo por medio del método  seekToEndOfFile
  7. Si desea mover el apuntador a un lugar en específico, puede utilizar el método seekToFileOffset el cual le permite especificar el lugar exacto dentro del archivo. 
  8. Para identificar el lugar donde se encuentra el apuntador, puede hacerlo con el método offsetInFile
  9. Para que el apundador puede almacenar su ubicación en un archivo muy grande, su tipo es un entero  unsigned long long.
Por ejemplo:

NSFileHandle * archivo;

archivo = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/archivo.txt"];

if (archivo == nil)
        NSLog(@"Error al abrir el archivo");

NSLog (@"Offset = %llu", [archivo offsetInFile]);

[archivo seekToEndOfFile];

NSLog (@"Offset = %llu", [archivo offsetInFile]);

[archivo seekToFileOffset: 30];

NSLog (@"Offset = %llu", [archivo offsetInFile]);

[archivo closeFile];

 Leer datos en un archivo

  1. Una vez que se ha abierto el archivo y que tenemos la referencia, el contenido del mismo puede ser leido a partir de la posición del apuntador (offset).
  2. El método readDataOfLength lee un número especificado de números de bytes a partir del apuntador (offset). 
  3. Por ejemplo, el siguiente código lee 5 bytes a partir de la posiciçon 10 a partir del inicio del archivo. 
  4. La información leída es encapsulada dentro de un objeto NSData:

NSFileHandle * archivo;
NSData *databuffer;

archivo = [NSFileHandle fileHandleForReadingAtPath: @"/tmp/archivo.txt"];

if (archivo == nil)
        NSLog(@"Failed to open file");

[archivo seekToFileOffset: 10];

databuffer = [archivo readDataOfLength: 5];

[archivo closeFile];

El método readDataToEndOfFile lee los datos encontrados desde el offset hasta el fin del archivo.

Escribir los datos en el archivo

El método writeData escribe la información encontrada en un objeto NSData a partir de la ubicación del apuntador u offset.
Este proceso no inserta datos, más bien los sobre escribe.
Para ver este comando en acción, cree un archivo de texto con la sentencia:

hola, cara de bola

A continuación ejecute el siguiente código:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {

        NSFileHandle * archivo;
        NSMutableData *data;

        const char *bytestring = "black dog";

        data = [NSMutableData dataWithBytes:bytestring length:strlen(bytestring)];


        archivo = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/archivo.txt"];

        if (archivo == nil)
                NSLog(@"Error al abrir el archivo");


        [archivo seekToFileOffset: 10];

        [archivo writeData: data];

        [archivo closeFile];

    }
    return 0;
}

Abra con un editor el archivo para ver el cambio.

Truncar un archivo

Un archivo puede ser truncado por medio del método truncateFileAtOffset.
Para borrar todo el contenido del archivo, el apuntador u offset deberá encontrarse al inicio del archivo, es decir, ser cero:

        NSFileHandle * archivo;

        archivo = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/archivo.txt"];

        if (archivo == nil)
                NSLog(@"Error al abrir el archivo");

        [archivo truncateFileAtOffset: 0];

        [archivo closeFile];
 

domingo, 4 de noviembre de 2012

Manejo de directorios en Objective-C


Un elemento clave en cualquier sistema que no sea muy pequeño, es el manejo de archivos. Por lo general, el manejo de archivos en el lenguaje C, en el cual se basa Objectibve-C, siempre es un poco complicado. Sin embargo, el framework Foundation, nos ayudará con varios métodos que nos harán la vida menos complicada, bueno, al menos el manejo de los archivos.

Las clases NSFileManager, NSFileHandle y NSData

NSFileManager - Esta clase puede ser utilizada para realizar operaciones básicas con archivos o carpetas como crear, mover, leer y escribir archivos y leer y modificar los atributos de los mismos. También cuenta con métodos para manejar los directorios, como leer su contenido, moverlos, borrarlos, etc.

  • NSFileHandle - Esta clase provee de operaciones de bajo nivel y de alto rendimiento, como búsqueda, lectura y escritura de arrchivos.
  • NSData - Esta clase maneja un buffer donde se puede leer y escribir los datos en un archivo.

Los nombre de las rutas de los archivos en Objective-C

Para las clases que se mencionan, los caminos de los archivos se manejan como en UNIX. Utilizamos la diagonal (/) para separar las carpetas. Si no inicia con la diagonal, entonces se considera a partir del directorio actual.

La carpeta inicial (o home) del cual puede el usuario iniciar, se maneja con una tilde (~). Su un archivo se escribe como  ~/miArchivo.m se hace referencia al archivo raiz del usuario. También se puede hacer la referencia a un directorio raíz de un usuario por medio de la tilde, por ejemplo ~pancho/demo.m, busca el directorio raíz del usuario "pancho".

Obteniendo la referencia por omisión con el objeto NSFileManager

La clase NSFileManager contiene un método llamado defaultManager podemos obtener la referencia a la carpeta donde se encuentra la aplicación:

NSFileManager *raiz;
raíz = [NSFileManager defaultManager];

A partir de este archivo, podemos utilizarlo de como apuntador para a partir de él, leer archivos y directorios.

Definir el directorio actual

El directorio de trabajo se puede obtener con el método currentDirectoryPath de la clase  NSFileManager. El método regresa el valor como una cadena NSString:

NSFileManager *raiz;
NSString *directorioActual;

raiz = [NSFileManager defaultManager];

directorioActual = [raiz currentDirectoryPath];

NSLog (@"El directorio actual es %@", directorioActual);

Cambio de directorio

Por medio del método changeCurrentDirectoryPath podemos cambiar de directorio de la aplicación. El nuevo destino del directorio es pasada como parámetro como un objeto NSString. Este método regresará un valor Booleano (YES/NO) para indicar si el cambio se efectuó en forma exitodsa o si existió un error:

NSFileManager *raiz;
NSString *dirActual;

raiz = [NSFileManager defaultManager];

dirActual = [raiz currentDirectoryPath];

NSLog (@"El directorio actual es %@", dirActual);

if ([raiz changeCurrentDirectoryPath: @"/temp/mydir"] == NO)
        NSLog (@"Error al cambiar de directorio.");

dirActual = [raiz currentDirectoryPath];

NSLog (@"El directorio actual es %@", dirActual);

Crear un nuevo directorio

Podemos crear un nuevo directorio por medio del método createDirectoryAtURLpasándole como un argumento a una instancia de la clase NSURL. Podemos pasarle diferentes atributos para el directorio:

NSFileManager *raiz;

raiz = [NSFileManager defaultManager];
NSURL *newDir = [NSURL fileURLWithPath:@"/tmp/mynewdir"];
[raiz createDirectoryAtURL: newDir withIntermediateDirectories:YES attributes: nil error:nil];

El método createDirectoryAtURL regresa un valor booleano indicando si la operación fue exitosa o no.

Borrar un directorio

Un directorio puede ser borrado del disco del sistema utilizando el mètodo removeItemAtPath, pasando como argumento el directorio que se desee eliminar:

An existing directory may be removed from the file system using the removeItemAtPath method, passing though the path of the directory to be removed as an argument:
 
NSFileManager *raiz;

raiz= [NSFileManager defaultManager];

[raiz removeItemAtPath: @"/tmp/mynewdir" handler: nil];

Renombrar o mover un directorio

Un directorio puede ser movido o renombreado usando el método moveItemAtURL. Este método toma como argumentos el origen y el destino por medio de objetos NSURL y es necesario que el objeto final NO EXISTA. Si el objeto destino ya existe, el étodo regresara un valor booleano negativo (NO):

NSFileManager *raiz;

raiz = [NSFileManager defaultManager];

NSURL *dirOrigen= [NSURL fileURLWithPath:@"/tmp/mynewdir"];
NSURL *dirNuevo= [NSURL fileURLWithPath:@"/tmp/mynewdir2"];

[raiz moveItemAtURL: dirOriegan toURL: dirNuevo error: nil];

Leer la lista de archivos del directorio

La lista de los archivos contenidos en un directorio se puede obtener por medio del método contentsOfDirectoryAtPath. Este método toma como argumento el camino del directorio que se desea leer como una cadena NSString y regresa un arreglo con los nombre de los archivos y subdirectorios contenidos:

NSFileManager *raiz;
NSString *dirActual;
NSArray *listaArchivos;
int num;
int i;

raiz= [NSFileManager defaultManager];

listaArchivos= [raiz contentsOfDirectoryAtPath: @"/tmp" error: nil];

num= [listaArchivos count];

for (i = 0; i < num; i++)
        NSLog (@"%@", [listaArchivos objectAtIndex: i]);

viernes, 2 de noviembre de 2012

Objective-C


Arreglos

Un arreglo (vector o matriz, depende del país) es un objeto que contiene colecciones de otros objetos. Los objetos Array en Objective-C se manejan con la clase NSArray

La clase NSArray contiene una serie de métodos específicamente diseñados para facilitar la creación y manipulación de los arreglos dentro de los programas de Objective-C. 

A diferencia de otros lenguajes de programación orientados a objetos (C # es un ejemplo), los objetos contenidos en un arreglo no todas tienen que ser del mismo tipo.

Arreglos mutables e inmutables


Los arreglos  en Objective-C vienen en dos sabores: inmutables y mutables. El contenido de un arreglo "inmutable" no puede cambiar en tiempo de ejecución. Los arreglos inmutables se crean como instancia de la clase NSArray. Los arreglo "mutables" se crean mediante la clase NSMutableArray (una subclase de NSArray) y puede ser modificada después de haber sido creado e inicializado.

Crear un arreglo

La clase NSArray contiene un método de clase llamado arrayWithObjects que se puede recurrir para crear un nuevo objeto Array y se inicializa con elementos. Por ejemplo:

NSArray *aColores;

aColores = [NSArray arrayWithObjects: @"Rojo", @"Verde", @"Azul", @"Amarillo", nil];

Es necesario añadir una entrada de tipo nil (en otros lenguajes es null, pero en Objective-C es nil) para que los métodos que se relacionan con los arreglos sepan donde termina este. Si omites la ultima entrada como nil, puede haber errores al momento de ejecutar tu aplicación.

Para crear un arreglo mutable que permitirá a los contenido de la matriz a modificar, tenemos que utilizar la clase NSMutableArray:

NSMutableArray *misColores;

misColores = [NSMutableArray arrayWithObjects: @"Rojo", @"Verde", @"Azul", @"Amarillo", nil];

Número de elementos de un arreglo


Para saber cuantos elementos tiene un arreglo, utilizamos el método count:

NSLog (@"Número de elementos en el arreglo = %lu", [misColores count]);

El índice de los arreglos, al igual que en la mayoría de los lenguaje que provienen de C, inicia en cero. Se puede acceder a los elementos de un arreglo, haciendo pasar la posición de índice a través de un argumento del método objectAtIndex

NSArray *misColores;
int i;
int lon;

misColores = [NSArray arrayWithObjects: @"Rojo", @"Verde", @"Azul", @"Amarillo", nil];

count = [misColores count];

for (i = 0; i < lon; i++)
        NSLog (@"Elemento %i = %@", i, [misColores objectAtIndex: i]);

Acceder a la información de un arreglo por medio de un ciclo for... in

NSArray *misColores;

misColores = [NSArray arrayWithObjects: @"Rojo", @"Verde", @"Azul", @"Amarillo", nil];


for (colores in misColores )
        NSLog (@"Elemento %@", color);

Añadir nuevos elementos a los arreglos mutables

Para añadir nuevos elementos a un arreglo mutable, lo realizaremos por medio del método addObject de la clase NSMutableArray. Por ejemplo:

[misColores addObject: @"Indigo"];
[misColores addObject: @"Violeta"];

Insertar elementos en un arreglo mutable por medio de un índice


Para insertar elementos en cualquier punto de un arreglo mutable, lo podemos efectuar por medio del método insertObject. Por ejemplo:

[misColores insertObject: @"Indigo" atIndex: 1];
[misColores insertObject: @"Violeta" atIndex: 3];

Borrar elementos de un arreglo

Objective_C nos proporciona muchos formas de  borrar elementos de un arreglo. Aquí se muestran las principales, pero puede ver la lista completa en la documentación de la librería Fundation.
Para borrar el elementos de un índice en específico se utiliza el método removeObjectAtIndex:
[misColores removeObjectAtIndex: 0];
Para borrar el primer elemento del arreglo utilice el método removeObject:
[misColores removeObject: @"Rojo"];

Para borrar un elemento por su contenido, utilice el método removeObjectIdenticalTo:
[misColores removeObjectIdenticalTo: @"Red"];

Para borrar todo el contenido de un arreglo, utilice el método removeAllObjects:
[misColores removeAllObjects];

Para borrar el último elemento de un arreglo, utilice el método  removeLastObject:
[misColores removeLastObject];

Ordenar un arreglo

Existen muchas formas de ordenar un arreglo. La más sencilla es por medio del método sortedArrayUsingSelector.

Por ejemplo:

NSMutableArray *misColore = [NSMutableArray arrayWithObjects: @"rojo", @"verde", @"azul", @"amarillo", nil];

NSArray *misColoresSorteados;

misColoresSorteados = [misColores sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
Como puede observarse, este método regresa otro objeto de tipo arreglo y utiliza el método localizedCaseInsensitiveCompare. Otros métodos que se pueden utilizar son NSOrderedAscendingNSOrderedSameNSOrderedDescending.