miércoles, 15 de diciembre de 2010

Clases NSString - NSArray - NSDictionary

1. NSString

1.1.    Lo que es

Las instancias de la clase NSString representan cadenas compuestas de caracteres unicode. Los caracteres unicode se describen mediante enteros de 16 bits; este tipo se denomina unichar en GNUstep pero es muy rara si alguna vez sucede la necesidad de trabajar con ello directamente. Unicode es un estándar que soporta los caracteres de casi todos los lenguajes.

1.2.    Instancias estáticas

La manera más fácil de crear una NSString es crear una instancia estática utilizando la construcción
@"...". Por ejemplo:

NSString *name = @"Nicola";

name apuntará a una instancia estática de NSString que contiene una representación unicode de la cadena ascii Nicola. Una instancia estática básicamente significa que es una instancia que se ha asignado en tiempo de compilación, son variables de instancia  y que no se pueden liberar.


1.3. stringWithFormat

Otra de las maneras fundamentales de crear una NSString es utilizando el método de clase +stringWithFormat:. Es un método de la clase NSString; acepta una lista de argumentos que se procesan de manera muy similar a como la función printf de la librería estándar de C procesa sus argumentos; la diferencia es que el resultado del método no se manda a la salida estándar, sino que se pone en una NSString que se devuelve como valor de retorno del método.
Por ejemplo:

int age = 25; 
NSString *message;
message = [NSString stringWithFormat: @"Your age is %d", age];

message será una NSString que contiene Your age is 25.
Una característica especial de stringWithFormat es que reconoce la conversión %@. Puede utilizarla para especificar otra NSString de la misma forma que utilizaría %s para especicar otra cadena de Con:

NSString *first; NSString *second;
first = @"Nicola"; second = [NSString stringWithFormat: @"My name is %@", first];

este código hace que la variable second contenga la cadena My name es Nicola.
De manera más general, puede utilizar la especicación %@ para mostrar la descripción de un objeto como la devuelta por NSObject -description. Esto se utiliza bastante durante el depurado:

NSObject *obj = [anObject someMethod]; NSLog (@"The method returned: %@", obj);


1.4.    Convirtiendo a y desde cadenas C
 Se utiliza a menudo para poder crear una NSString desde una cadena ascii estándar o de modo más general utf-8 que no es ja al compilar. Digamos, por ejemplo, que nuestro programa llama a una función de una librería de C
char *function(void);
que devuelve alguna información necesaria en una cadena de C. Queremos crear una NSString utilizando el contenido de esa cadena C. La manera más fácil de hacer esto es utilizar el método +stringUTF8String: de la clase NSString, como sigue:

char *result; NSString *string;
result    =    function ();
string = [NSString stringUTF8String: result];

Algunas veces necesitará realizar el proceso inverso, es decir: convertir una NSString en una cadena ascii de C estándar o de modo más general utf-8. Puede hacerlo utilizando el método -UTF8String de la clase NSString, como el siguiente ejemplo:

char *result; 
NSString *string;

string = @"Hello"; result = [string UTF8String];


1.5. NSMutableString

NSStrings son objetos inmutables, esto quiere decir, que aunque puede crear una NSString no puede modicarla. Esto permite a la librería de GNUstep optimizar el código de NSString. Si necesita poder modificar una cadena debe utilizar una subclase especial de NSString, llamada NSMutableString. Puesto que NSMutableString es una subclase de NSString puede utilizar NSMutableString allí donde se puede utilizar una NSString. Pero, una NSMutableString responde a métodos que le permiten modificar la cadena directamente, algo que no puede hacer con una NSString.
Para crear una NSMutableString puede utilizar +stringWithFormat:, como en el siguiente ejemplo:
NSString *name = @"Nicola"; 
NSMutableString *str;
str = [NSMutableString stringWithFormat: @"Hello, %@", name];

Mientras que la implementación de NSString +stringWithFormat: devolvía una NSString, la implementación de NSMutableString devuelve una NSMutableString. Las cadenas estáticas creadas con @"..." son siempre inmutables.
En la práctica, NSMutableString no se suele utilizar mucho, puesto que normalmente si quiere modificar una cadena lo que se hace es crear una nueva derivándola de otra que ya teníamos.
Posiblemente el método más interesante de la clase NSMutableString es -appendString:. Toma como argumento una NSString y lo añade al receptor.
Por ejemplo, el siguiente código:

NSString *name = @"Nicola"; 
NSString *greeting = @"Hello"; 
NSMutableString *s;
s = AUTORELEASE([NSMutableString new]); 
[s appendString: greeting]; 
[s appendString: @", "]; 
[s appendString: name];

donde hemos utilizado new para crear una NSMutableString produce el mismo resultado que lo siguiente:


NSString *name = @"Nicola"; 
NSString *greeting = @"Hello"; 
NSMutableString *s;
s    =    [NSMutableString    stringWithFormat:    @" %@,    %@",    greeting ,    name];


1.6.    Leyendo y guardando cadenas de/desde archivos

No tenemos tiempo para describir todas las funciones relativas a cadenas de la librería base de GNUstep; pero es útil, al menos, echar un vistazo rápido a lo fácil que es escribir/leer cadenas de/desde archivos.
Si necesita escribir el contenido de una cadena en un archivo, puede utilizar el método  

-writeToFile:atomically, como se muestra en el siguiente ejemplo:
#include <Foundation/Foundation.h>
int main(void) {
}
NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSString *name = @"This string was created with GNUstep";
if ([name {
writeToFile: @"/home/nico/testing" atomically: YES]) (@"Success");
(@"Faliure");
NSLog
} else
{
NSLog return 0;
}

-writeToFile:atomically devuelve YES cuando tiene éxito y NO cuando falla. Si el ag atomically es YES, la librería escribe primero la cadena en un archivo temporal y cuando la escritura ha tenido éxito, renombra el fichero al nombre especificado. Esto previene el borrado de la versión previa del fichero hasta que la escritura haya tenido éxito. Ésta es una característica muy buena que querrá tener activada.
Leer el contenido de un archivo a una cadena también es fácil. Simplemente puede utilizar +stringWithContentsOfFile:, como en el siguiente ejemplo, que lee @"/home/nicola/test":

#include <Foundation/Foundation.h>
int main(void) {
NSAutoreleasePool *pool = [NSAutoreleasePool new]; 
NSString *string; 
NSString *filename = @"/home/nicola/test";
string = [NSString stringWithContentsOfFile: filename]; 
if (string == nil)
{
NSLog (@"Problem reading file %@", filename); // <missing code: do something with the error...> // <exit perhaps ?>
} * <missing code: do something with string...>

/*
}
*/ return 0;


2. NSArray

2.1.    Lo que es
Las instancias de NSArray representan arrays de objetos. Es decir, un NSArray se utiliza para almacenar un conjunto ordenado de objetos.

2.2.    Comparación con los arrays de C
En una herramienta o aplicación GNUstep, puede utilizar también arrays C puros, exactamente como lo haría en C. NSArrays tiene algunas ventajas y desventajas sobre los arrays de C. La primera ventaja es que la interfaz del programador es ligeramente más sencilla y hace el código fácil de leer, mantener y depurar. En particular, si utiliza arrays modificables (NSMutableArray), la librería GNUstep reduce o expande el array por usted como se necesite cuando se añaden o eliminan objetos, sin que tenga que asignar manualmente o redimensionar la memoria necesaria para el array. La segunda ventaja de NSArray es que proporciona utilidades para hacer cosas que no son precisamente sencillas de hacer con los arrays de C. En la última sección de este tutorial aprenderemos una de estas facilidades: la habilidad de guardar un array de cadenas (u otros objetos sencillos) en un fichero de texto plano y, automáticamente, recrear el array con la información leída desde el fichero. La principal desventaja es que un NSArray es significativamente más lento que un array de C, pero no debe sobrestimar este problema que es realmente importante cuando necesita código realmente rápido y tiene que iterar en arrays realmente grandes. Muchas veces usar un array de C o un NSArray no produce diferencias reales en el rendimiento, pero por supuesto en otras ocasiones sí lo tiene.


2.3.    Los NSArray son inmutables
Como en el caso de las cadenas, NSArray es inmutable, no puede cambiarlos después de creados esto le permite al código de NSArray de GNUstep algunas optimizaciones que serían imposibles de otra manera. Si necesita un array que pueda modificar puede utilizar un subtipo de NSArray llamado NSMutableArray. Esto ocurre bastante a menudo, por eso profundizaremos en ello más adelante.


2.4.    arrayWithOb jects
Para crear un NSArray normalmente utilizará el método de clase +arrayWithObjects:, que toma como argumento una lista de objetos terminada en nil para ponerlos en el array:

NSArray *names;
names = [NSArray arrayWithObjects: @"Nicola", @"Margherita", @"Luciano", @"Silvia", nil];

El último elemento en la lista debe ser nil para marcar el final de la lista. Puede poner en el mismo array objetos de diferentes clases:

NSArray *objects; NSButton *buttonOne; 
NSButton *buttonTwo; 
NSTextField *textField;
buttonOne buttonTwo textField
objects =
= AUTORELEASE ([NSButton new]); = AUTORELEASE ([NSButton new]); = AUTORELEASE ([NSTextField new]);
[NSArray    arrayWithObjects:    buttonOne , textField ,
buttonTwo , nil];

pero no puede poner nil en un array. Todos los objetos deben ser válidos, no objetos nil.
Cuando se pone un objeto en un array, el NSArray le envía un mensaje -retain para evitar que sea liberado mientras está siendo utilizado en el array. Cuando se borra un objeto de un array porque el array es un NSMutableArray y por tanto se pueden quitar objetos de él o porque el array mismo está siendo liberado se le envía un mensaje -release.


2.5.    Accediendo a los objetos en un NSArray

Para acceder a un objeto en un NSArray utilice el método -objectAtIndex: como en el siguiente ejemplo:
NSArray *numbers; NSString *string;
numbers = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil]; 
string = [numbers objectAtIndex: 2]; // @"Three"

Por supuesto, debe tener cuidado de no preguntar por un objeto con un índice negativo o mayor que el tamaño del array; si lo hace se lanzará una NSRangeException (puede aprender más sobre excepciones en otro tutorial).
Para obtener el largo de un array utilice el método -count, como en:

NSArray *numbers; int i;
numbers = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil]; i = [numbers count]; // 3

2.6.    Describiendo un array
A veces es útil para depurar echar un vistazo a lo que se almacena den- tro de un array. Nada más fácil con la librería base de GNUstep: todos los métodos y funciones que toman argumentos de formato del modo en que lo hace +stringWithFormat: reconocen la especicación de conversión%@, que describe un objeto. Por eso, para describir el NSArray llamado array, sólo tiene que hacer:
NSLog (@"Array: %@", array);
Por ejemplo, un array creado con NSArray *array;
array = [NSArray arrayWithObjects: @"Hi", @"Hello", AUTORELEASE ([NSLock new]),
nil ];
se describirá por la anterior llamada a NSLog como: Jan 08 08:50:38 Test[16808] Array: (Hi, Hello, <NSLock: 8081f98>)

Observe que no es fácil obtener una descripción completa de un array de C.

2.7.    Iterando sobre los elementos de un array 

2.7.1.    Primera forma: utilizando objectAtIndex:

Para iterar sobre los elementos de un array, simplemente, puede utilizar la manera en como se hace en C, como en la siguiente rutina de depuración que imprime una descripción de los objetos que hay en un  
NSArray:
void describeArray(NSArray *array) {
int i, count;
count = [array count]; for (i = 0; i < count; i++) {
NSLog (@"Object at index %@ is: %@", i, [array objectAtIndex: i]);
}

Por supuesto, este código es, en cierto modo inútil, porque se puede obtener la descripción completa de la matriz en una llamada única a NSLog, como vimos en la sección anterior; pero cumple con el propósito de mostrar cómo se itera sobre los elementos de un array.

2.7.2.    Segunda forma: utilizando objectEnumerator

Hay otra manera muy importante de iterar sobre los elementos de un array, que es usar el método -objectEnumerator. 
Este método devuelve un objeto de la clase NSEnumerator que tiene un método llamado -nextObject. La primera vez que lo invoque devolverá el primer elemento del array. La segunda vez que lo invoque devolverá el segundo elemento del array y así hasta que no queden más objetos en el array; en ese momento, el NSEnumerator devolverá nil. En el siguiente ejemplo, el código para describir un array se ha reescrito utilizando esta segunda forma:

void describeArray(NSArray *array) {
NSEnumerator *enumerator; NSObject *obj;
enumerator = [array objectEnumerator];
while ((obj = [enumerator nextObject]) != nil) {
NSLog (@"Next object is %@", obj);
}

Esta segunda forma es signicativamente más rápida que la primera pero tiene una importante restricción: no debe modicar el array (si es un NSMutableArray) mientras enumera sus miembros de esta manera. Sea cuidadoso con este prob- lema porque es fácil saltárselo y puede introducir sutiles bugs.

2.8.    Buscar un objeto
Si quiere comprobar cuándo un NSArray contiene un objeto o no, debe uti- lizar el método -containsObject: como en el siguiente ejemplo:

NSArray *array;
array = [NSArray arrayWithObjects: @"Nicola", @"Margherita", @"Luciano", @"Silvia", nil];
if ([array containsObject: @"Nicola"]) // YES {
// Hacer algo
}
-containsObject: compara objetos utilizando -isEqual:, que es lo que se quiere normalmente, por ejemplo, dos cadenas que contienen los mismos carac- teres unicode son consideradas iguales, incluso si no son el mismo objeto.
Para obtener el índice de un objeto debe utilizar -indexOfObject:, que devuelve el índice del objeto mejor, de un objeto igual al argumento, o la constante NSNotFound si no se puede encontrar un objeto igual en el array, como en el siguiente ejemplo:

NSArray *array; int i, j;
array = [NSArray arrayWithObjects: @"Nicola", @"Margherita", @"Luciano", @"Silvia", nil];
i = [array indexOfObject: @"Margherita"]; // 1 j = [array indexOfObject: @"Luca"];    // NSNotFound
}
 

2.9. NSMutableArray

Si necesita añadir, reemplazar o borrar elementos en un array debe utilizar un NSMutableArray. En general, puede crear un NSMutableArray utilizando

NSMutableArray *array; array = [NSMutableArray new];

También, si fuera necesario podríamos hacer un autorelease. Esto crea un NSMutableArray que no contiene elementos.


2.9.1.    Añadir un objeto 

Para añadir un elemento al final del array puede utilizar addObject como en: 
NSMutableArray *array;
array = [NSMutableArray new]; [array addObject: anObject];
Asumiendo que anObject es un NSObject pero no nil, recuerde que no puede poner un objeto nil en un NSArray. Como es normal a anObject se le hace un retain cuando se le añade al array.
Si lo que quiere es insertar un objeto en una determinada posición puede utilizar insertObject:atIndex:.
NSMutableArray *array;
array = [NSMutableArray new]; [array addObject: @"Michele"]; [array addObject: @"Nicola"]; [array insertObject: @"Alessia" atIndex: 1];
/*    Ahora    el    array    contiene    Michele ,    Alessia ,    Nicola.    */


2.9.2.    Quitar un objeto 
Para eliminar un objeto del array puede utilizar removeObjectAtIndex:, como en
NSMutableArray *array;
array = [NSMutableArray new]; [array addObject: @"Michele"]; [array addObject: @"Nicola"]; [array insertObject: @"Alessia" atIndex: 1];
/*    Ahora    el    array    contiene    Michele ,    Alessia ,    Nicola.    */ [array removeObjectAtIndex: 0]; /* Ahora el array contiene Alessia, Nicola */
9
Cuando se quita un objeto de un array recibe un mensaje release. Esto equilibra el retain que se le envió cuando se le añadió previamente al array y permite que el objeto sea liberado si es necesario.


2.9.3.    Reemplazar un objeto
Para sustituir un objeto puede utilizar replaceObjectAtIndex:withObject:, como en
NSMutableArray *array;
array = [NSMutableArray new]; [array addObject: @"Alessia"]; [array addObject: @"Michele"];
/* Ahora el array contiene Alessia, Michele. */ [array replaceObjectAtIndex: 1 withObject: @"Nicola"]; /* Ahora el array contiene Alessia, Nicola */
El objeto que se ha quitado del array ��porque está siendo sustituido�� recibe un mensaje release; el objeto que se añade al array (porque está sustituyendo al otro objeto) recibe un mensaje retain.

3. NSDictionary

3.1.    Lo que esUna instancia de NSDictionary contiene un conjunto de claves, y por cada clave, un valor asociado. Tanto claves como valores deben ser objetos; las claves deben ser diferentes unas de otras, y no deben ser nil; los valores no pueden ser nil.
{
}
Un ejemplo de NSDictionary puede ser representado como sigue:
Luca = "/opt/picture.png"; "Birthday Photo" = "/home/nico/birthday.png"; "Birthday Image" = "/home/nico/birthday.png"; "My Sister" = "/home/marghe/pic.jpg";
En este ejemplo, cada clave (Luca, etc.) es una cadena el nombre de una imagen que se asocia a un valor (/opt/picture.png) que es una cadena con el path completo al archivo que contiene la imagen. Observe que distintas claves pueden apuntar al mismo valor. En este caso, se puede acceder al mismo archivo de imagen utilizando dos nombres diferentes.
En el ejemplo, todos los objetos son cadenas, pero no es necesario que sea siempre así; claves y valores pueden ser objetos arbitrarios no necesariamente de la misma clase. Una diferencia básica entre NSArray y NSDictionary es que los elementos de un NSArray están alineados en un orden preciso, mientras que los pares clave/valor en un NSDictionary no guardan ningún orden. Normalmente se accede a un elemento en un array indicando su posición ��su índice��; sin embargo, en un diccionario se pregunta por el valor asociado a una determinada clave. Por eso, mientras los arrays se usan para mantener una lista ordenada de objetos, los diccionarios se utilizan para guardar mapas entre ciertas claves y valores. En otros contextos a los diccionarios se les llama hash tables.


3.2.    Creando un NSDictionary

Para crear un NSDictionary puede usar el método +dictionaryWithObjectsAndKeys:
que toma como argumento una lista de objetos ��considerados como pares, el primero es el valor y el segundo la clave; la lista se termina en nil. El siguiente ejemplo crea el diccionario utilizado como ejemplo en la sección anterior:
NSDictionary *dict;
dict = [NSDictionary dictionaryWithObjectsAndKeys: @"/opt/picture.png", @"Luca",
@"/home/nico/birthday.png", @"Birthday Photo", @"/home/nico/birthday.png", @"Birthday Image", @"/home/marghe/pic.jpg", @"My Sister", nil];
Por favor, observe que las claves siguen a sus valores en lugar de precederlos.


3.3.    Obteniendo un objeto con objectForKey:
Para recuperar un valor asociado con una clave debe utilizar el método -objectForKey:, como en el siguiente ejemplo:
NSDictionary *dict; NSString *path;
dict = [NSDictionary dictionaryWithObjectsAndKeys: @"/opt/picture.png", @"Luca",
@"/home/nico/birthday.png", @"Birthday Photo", @"/home/nico/birthday.png", @"Birthday Image", @"/home/marghe/pic.jpg", @"My Sister", nil];
// Ahora fijamos path a /home/nico/birthday.png path = [dict objectForKey: @"Birthday Image"];
Si la clave no está en el diccionario, -objectForKey: devolverá nil, por ejemplo
// Lo siguiente establece el path a nil path = [dict objectForKey: @"My Mother"];
asumiendo que dict es el que creamos en el ejemplo anterior��. En las aplicaciones de la vida real, en la mayoría de los casos no necesita saber si una clave está en el diccionario o no mientras compruebe el valor asociado devuelto con ella. En estos casos, necesita comprobar el resultado de
objectForKey:11
asegurándose de que no es nil antes de utilizarlo. Por ejemplo, suponiendo que dict es un diccionario, podría hacer
NSString *imageName = @"My Father"; NSString *path;
path = [dict objectForKey: imageName];
if (path == nil) {
} else
{ }
// Esto quiere decir que el diccionario no lo contiene NSLog (@"No conozco el path a la imagen '%@'", imageName);
// Hacer algo con el path
Esta es la manera habitual de comprobar si una clave existe en el diccionario: llama a objectForKey y compara el resultado con nil.

3.4.    Enumerando todas las claves y valores
Algunas veces necesitará iterar sobre todos los pares clave/valor de un dic- cionario. Para hacer esto, utilice el método -allKeys que devuelve un array con todas las claves del diccionario; este array contiene todas las claves sin un orden particular. Puede recorrer ese array y obtener el valor para cada clave. El siguiente ejemplo imprime todos los pares clave-valor del diccionario:
void describeDictionary (NSDictionary *dict) {
}
NSArray *keys; int i, count; id key, value;
keys = [dict allKeys]; count = [keys count]; for (i = 0; i < count; i++)
{
}
key = [keys objectAtIndex: i]; value = [dict objectForKey: key]; NSLog (@"Clave: %@ para el valor: %@, key, value);
Este código es sólo un ejemplo de como enumerar todas las entradas del diccionario; en la vida real, para obtener una descripción del diccionario, sólo tiene que hacer NSLog (@" %@", miDiccionario);.

3.5. NSMutableDictionary
Un NSDictionary es inmutable. Cuando necesite un diccionario que se pueda modificar, deberá utilizar NSMutableDictionary.
NSMutableDictionary es una subclase de NSDictionary, por eso puede hac- er con un NSMutableDictionary todo lo que podría hacer con un NSDictionary y además puede modi��carlo.
Para establecer el valor para una clave, se utiliza el método -setObject:forKey:. Si la clave no existe en el diccionario se añade con el valor dado. Si la clave ya existía en el diccionario se elimina el valor anterior (con el efecto colateral de que se le envía un mensaje -release), y el valor nuevo se coloca en su lugar (como es habitual, el nuevo recibe un mensaje -retain). Observe que mientras los valores se retienen, las claves sólo se copian.
Así, si utiliza NSMutableDictionary puede crear un diccionario como sigue:
NSMutableDictionary *dict;
dict = [NSMutableDictionary new]; AUTORELEASE (dict); [dict setObject: @"/opt/picture.png"
forKey: @"Luca"]; [dict setObject: @"/home/nico/birthday.png"
forKey: @"Birthday Photo"]; [dict setObject: @"/home/nico/birthday.png"
forKey: @"Birthday Image"]; [dict setObject: @"/home/marghe/pic.jpg"
forKey: @"My Sister"];
Para eliminar una clave y su valor asociado, sólo tiene que utilizar el método -removeObjectForKey:.
[dict removeObjectForKey: @"Luca"];
Esto eliminará la clave @"Luca" y su valor asociado de un diccionario muta- ble.

4.    Listas de propiedades
Como se prometió, en esta última sección le echaremos un vistazo rápido a una característica muy interesante de GNUstep: el soporte de las listas de propiedades. Como se dijo es muy fácil guardar/cargar una cadena en/desde un archivo. GNUstep va mucho más allá de esto. Puede guardar/cargar cualquier objeto en/desde un archivo, utilizando las facilidades archivar/recuperar; esto es una gran facilidad pero se guardan/cargan en formato binario. Para arrays y diccionarios que contienen sólo cadenas, GNUstep proporciona otras utili- dades (las que aquí nos interesan) para guardarlas/leerlas desde ��cheros con un formato humanamente legible y humanamente modificable, llamada lista de propiedades. Actualmente, el conjunto de objetos que puede guardar o leer de esta manera es mucho más general:
1. Cualquier cadena puede guardarse/leerse como una lista de propiedades.
2. Unarrayodiccionarioconteniendosóloobjetosquesepuedanguardar/leer como una lista de propiedades también puede ser guardado/leído como una lista de propiedades.
En la práctica, cualquier array o diccionario que contienen otros arrays o dic- cionarios se pueden guardar/leer de esta manera si los objetos ����nales�� son cadenas.
Para guardar o leer un diccionario o un array del tipo correcto, los puede es- cribir o leer en/desde un archivo de la misma manera que lo hace con las cadenas, esto es, con el método -writeToFile:atomically: para escribirlos en el archi- vo, y el método +dictionaryWithContentsOfFile: para diccionarios o el método +arrayWithContentsOfFile: ��para arrays�� para leerlos desde archivos.
Por ejemplo, el siguiente código crea un diccionario que se utilizar para almacenar algo de información para cada persona; luego lo guarda en un ��chero en formato de lista de propiedades:
#include <Foundation/Foundation.h>
int main(void) {
}
NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSMutableDictionary *dict; NSDictionary *dict2;
dict = [NSMutableDictionary new]; AUTORELEASE (dict);
dict2 = [NSDictionary dictionaryWithObjectsAndKeys: @"Nicola", @"Name",
@"Pero", @"Surname",
@"n.pero@mi.flashnet.it", @"Email", nil]; [dict setObject: dict2 forKey: @"Nicola"];
dict2 = [NSDictionary dictionaryWithObjectsAndKeys: @"Ettore", @"Name",
@"Perazzoli", @"Surname",
@"ettore@helixcode.it", @"Email", nil]; [dict setObject: dict2 forKey: @"Ettore"];
dict2 = [NSDictionary dictionaryWithObjectsAndKeys: @"Richard", @"Name",
@"Frith -MacDonald",    @"Surname",
@"richard@brainstorm.com.uk", @"Email", nil]; [dict setObject: dict2 forKey: @"Richard"];
if ([dict writeToFile: @"/home/nico/testing" atomically: YES]) {
} else
{
NSLog (@"Success");
NSLog (@"Faliure"); return 0;
}

He probado esto en mi máquina (le animo a que haga lo mismo en la suya) y escribió lo siguiente en mi archivo /home/nico/testing:
{
}
Ettore = { Email = "ettore@helixcode.com"; Name = Ettore; Surname = Perazzoli;
}; Nicola = {
Email = "n.pero@mi.flashnet.it"; Name = Nicola; Surname = Pero;
}; Richard = {
Email = "richard@brainstorm.co.uk"; Name = Richard; Surname = "Frith-MacDonald";
};
Como puede observar es un formato bastante simple y sencillo de leer y editar manualmente. Las " (comillas) se utilizan donde una cadena contiene espacios o caracteres especiales; se omiten para cadenas simples. Los diccionarios se salvan como en
{
}
Email = "richard@brainstorm.co.uk"; Name = Richard; Surname = "Frith-MacDonald";Observe que se utilizan llaves y cada par clave/valor está terminado por un punto y coma (;) incluso en el último. Los arrays que no se muestran en el ejemplo anterior se guardan como
(
)
"Nicola Pero", "Ettore Perazzoli", "Richar Frith-MacDonald"

Se utilizan paréntesis y cada elemento está seguido con una coma excepto el último. Puede encontrar otros ejemplos de este formato mirando en su di- rectorio /GNUstep. Una de las ventajas de este formato es que aún siendo muy general es muy portable y sencillo. Es tan fácil y sencillo (al menos como XML) que se puede escribir un parser para leerlo y escribirlo en un par de días.
Cuando tiene guardada información con el formato de lista de propiedades puede obtenerla desde el mismo archivo fácilmente. El código siguiente obtiene los datos desde el archivo /home/nico/testing e imprime el Email de Ettore:
#include <Foundation/Foundation.h>
int main (void) {
}
NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSDictionary *dict; NSDictionary *dict2; NSString *email;
dict = [NSDictionary dictionaryWithContentsOfFile: @"/home/nico/testing"];
dict2 = [dict objectForKey: @"Ettore"]; email = [dict2 objectForKey: @"Email"];
NSLog (@"El Email de Ettore es: %@", email); return o;

No hay comentarios:

Publicar un comentario

468x60