Objective-C desde Cero: Strings, Números y Colecciones

Publicado el 29 julio 2013 por Codehero @codeheroblog

En el capítulo anterior hablamos de como hacer nuestras propias clases.

En el capítulo de hoy hablaremos de algunas de las clases más usadas que provee Apple en su Foundation Framework. Estas clases nos hacen la vida más fácil proporcionándonos manejo de objetos básicos sin tener que preocuparnos nosotros por ellos.

Hoy hablaremos sobre cadenas de caracteres o Strings, y de la clase NSNumber para manejar objetos con números. En cuando a colecciones tocaremos las más importantes: NSArray, NSMutableArray, NSDiccionary y NSMutableDiccionary.


Empezando

Como siempre abrimos Xcode y esta vez crearemos un nuevo proyecto de tipo “Command Line Tool”.

Yo voy a llamar a mi proyecto “Clases de Apple”. Usaremos “Automatic Reference Counting”


Strings

Los strings son cadenas de caractes Unicode estáticas para representar texto. Cuando digo estáticas me refiero a que una vez instanciado un string no podemos cambiar su contenido a menos de lo volvamos a inicializar con otro valor.

En Objective-C la clase NSString es la que maneja estas cadenas de caracteres.

Entonces, vamos a abrir Xcode y nos vamos a main.m. Borramos todo lo que este dentro del bloque @Autoreleasepool y vamos a crear un string.

NSString *test1 = @"Hola mundo";

Esta es la manera más fácil de inicializar un string. Utilizando la forma literal.

También podemos crear un string utilizando uno de los constructores de la clase.

NSString *test2 = [[NSString alloc] initWithString:test1];

En esta ocasión hemos inicializado test2 con el contenido de test1.

Existen muchos constructores y métodos estáticos que inicializan la clase NSString. Con ellos podemos incluir otros tipos de datos y hacerlos formar parte del texto que queramos formar.

int anInteger = 48;
        
NSString *test3 = [NSString stringWithFormat:@"El numero es: %i", anInteger];

%i es reemplazado por el valor de la variable anInteger. Dependiendo del tipo de dato de la variable el especificador de formato varía. Por ejemplo, si la variable fuera de tipo double, usaríamos %d, si fuera otro string usaríamos %@. Para conocer más sobre especificadores de formato, te invito a revisar la documentación de Apple.

Strings mutables

Los strings mutables son aquellos que se pueden modificar, es decir, una vez inicializados se les puede agregar o quitar caracteres.

NSMutableString *test4 = [NSMutableString stringWithFormat:@"Hola "];
[test4 appendString:@"mundo"];
        
NSLog(@"test4 contiene: %@", test4);

Aquí vemos como he creado el string test con el valor “Hola “ y luego le he agregado la palabra “mundo”. Si corremos ahora esta aplicacion veremos como imprimirá por consola

test4 contiene: Hola mundo

Colecciones

Las colecciones son objetos que permiten manejar grupos de objetos del mismo tipo o distintos.

NSArray

Los arrays o arreglos también tienen varias formas de instanciarse:

NSArray *testArray = @[test1, test2, test3, test4];

Esta es la forma literal. En este caso he creado un array con todos los strings que creé anteriormente. Ahora vemos como se hace por el constructor.

NSArray *testArray2 = [[NSArray alloc] initWithObjects:test1, test2, test3, test4, nil];

Cuando declaramos arrays en esta forma siempre debemos cerrar con nil.

Si queremos obtener un valor del array, lo hacemos de la siguiente manera:

NSString *string = [testArray objectAtIndex:2];

Los arrays son estáticos, al igual que los NSString no se pueden modificar una vez inicializados.

NSMutableArray

La contraparte modificable de NSArray es NSMutablearray.

// 1
NSMutableArray *testMutableArray = [[NSMutableArray alloc] initWithArray:testArray];
NSLog(@"testMutableArray: %@", testMutableArray);

// 2
[testMutableArray addObject:testArray2];
NSLog(@"testMutableArray: %@", testMutableArray);

// 3
[testMutableArray removeObjectAtIndex:2];
NSLog(@"testMutableArray: %@", testMutableArray);

// 4
[testMutableArray removeLastObject];
NSLog(@"testMutableArray: %@", testMutableArray);

// 5
[testMutableArray removeAllObjects];
NSLog(@"testMutableArray: %@", testMutableArray);

Bien, aquí vemos algunas cosas que podemos hacer con el NSMutableArray:

  1. Se instancia la clase con el contenido de un array. También podemos instanciar un mutable array sin otro array, utilizando initWithObjects al igual que NSArray;
  2. Agregué testArray2 a testMutableArray. Cuando agregas se inserta al final de la lista;
  3. Aquí elimino de la lista el objeto en la posición 2;
  4. Así elimino el objeto en la ultima posición;
  5. Y por último elimino todos los objetos que queden.

Por cada invocación que hice de los métodos de NSMutableArray hice un NSLog para que vieras como va cambiando el array.

NSDiccionary

Los diccionarios son colecciones inmutables (no se puede modificar una vez instanciado) de asociaciones clave-valor, es decir, por cada clave que se inserte, se debe insertar un valor.

NSDictionary *testDiccionary = @{@"valor 1": test1,
                                 @"valor 2": test2,
                                 @"valor 3": test3,
                                 @"valor 4": test4
                                 };

Para obtener valores del diccionario debemos pedirlo por clave:

NSString *string2 = [testDiccionary objectForKey:@"valor 2"];

NSMutableDiccionary

Los diccionarios mutables son aquellos que si se pueden modificar, al igual que NSMutableString y NSMutableArray.

// 1
NSMutableDictionary *testMutableDiccionary = [[NSMutableDictionary alloc] initWithDictionary:testDiccionary];
NSLog(@"testMutableDiccionary: %@", testMutableDiccionary);

// 2
[testMutableDiccionary setValue:testArray forKey:@"valor 5"];
NSLog(@"testMutableDiccionary: %@", testMutableDiccionary);

// 3
[testMutableDiccionary removeObjectForKey:@"valor 2"];
NSLog(@"testMutableDiccionary: %@", testMutableDiccionary);

// 4
[testMutableDiccionary removeObjectsForKeys:@[@"valor 4", @"valor 1"]];
NSLog(@"testMutableDiccionary: %@", testMutableDiccionary);

// 5
[testMutableDiccionary removeAllObjects];
NSLog(@"testMutableDiccionary: %@", testMutableDiccionary);
  1. Se instancia la clase con el contenido de un diccionario;
  2. Agregué testArray a testMutableDiccionary con la clave “valor 5″.;
  3. Aquí elimino el objeto con la clave “valor 2″;
  4. Así elimino los objetos con las claves “valor 4″ y “valor 1″;
  5. Y por último elimino todos los objetos que queden.

Igualmente imprimí por consola cada invocación que hice de los métodos de NSMutableDiccionary para que se viera como va cambiando el diccionario.

Números

Si quisiéramos crear un arreglo o un diccionario de números no podríamos porque los NSArray, NSMutableArray, NSDiccionary y NSMutableDiccionary, solo aceptan objetos como elementos de la colección y los números son tipos de datos primitivos (int, double, float, etc). Por esto es que Apple introdujo la clase NSNumber.

NSNumber es un envoltorio de estos tipos de datos primitivos para poder ser almacenados en colecciones. Veamos como se usan:

NSNumber *aNumber = [NSNumber numberWithInt:5];
NSNumber *aNumber2 = [NSNumber numberWithBool:YES];
NSNumber *aNumber3 = [NSNumber numberWithFloat:4.5f];

Aquí instanciamos tres NSNumber, unos con un int, otro con un BOOL y otro con un float.

Ahora, podemos agregarlos a un array:

NSArray *numbers = @[aNumber, aNumber2, aNumber3];

Si lo queremos volver a convertir en su valor original:

NSLog(@"aNumber: %i", [[numbers objectAtIndex:0] intValue]);
NSLog(@"aNumber2: %i", [[numbers objectAtIndex:1] boolValue]);
NSLog(@"aNumber3: %.1f", [[numbers objectAtIndex:2] floatValue]);

Aquí los pido al array numbers por su posición y luego al NSNumber que retorna le pido que me retorne su valor int, bool, float, etc, según sea el caso.


Conclusión

En este capítulo hemos aprendido a manejar unas de las clases más usadas al programar en Objective-C. Estas clases nos serán de mucha ayuda cuando trabajemos, por ejemplo, con tablas en iOS y Mac OS X.

Si tienes alguna pregunta no dudes en dejarla en los comentarios, con mucho gusto la responderé para ti.

Ya será hasta el próximo capítulo de Objective-C desde Cero.

Adiós.