11.06.2008

NSDictionary und NSMutableDictionary

In diesem Artikel werden die Klassen NSDictionary und NSMutableDictionary kurz beschrieben. Außerdem wird die Anwendung einiger weniger ausgewählter Funktionen demonstriert.

Die Erzeugung eines NSDictionary wird einmal mit der Funktion dictionaryWithObjects:forKeys und einmal mit der Funktion dictionaryWithObjectsAndKeys gezeigt. Zur Ausgabe wird einmal eine while-Schleife und einmal eine For..in-Schleife verwendet.

Die folgende Funktion zeigt die Verwendung von NSDictionary.

void dictionaryTest() {
	NSLog(@"dictionaryTest");

	//Create Keys
	NSArray* keys = [NSArray arrayWithObjects:@"1001", @"1002", @"1003", nil];

	//Create Values
	NSArray* values = [NSArray arrayWithObjects:@"MacBook 13.3 white", @"iPod 8GB", @"iPhone 16GB", nil];

	//Create dictionatry with keys and values
	NSDictionary* aDictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];

	//Declare an key
	NSString* key;

	//Get an enumerator for the keys of the dictionary
	NSEnumerator* aKeyEnum = [aDictionary keyEnumerator];

	//Iterate while there is a next object
	while( (key = [aKeyEnum nextObject]) ) {
		//Print key and value
		NSLog(@"%@ = %@",key, [aDictionary valueForKey:key]);
	}
}

In dem Beispiel wird der convenience Allocator dictionaryWithObjects:forKeys verwendet um ein NSDictionary mit key-value-Paaren zu füllen. Dazu werden zwei NSArrays erzeugt. Eines mit Schlüsseln (keys) und eines mit Werten (values). Diese werden beim Erzeugen des Dictionary als Parameter übergeben.

Die Ausgabe des gesamten Dictionary wird mit einer while-Scheife gelöst. Dazu wird ein NSEnumerator erzeugt, der seine Werte (keys) über die Nachricht keyEnumerator erhält. Dann wird einfach über die Schlüssel von aKeyEnum enumeriert. Der key kann sofort ausgegeben werden und der passende Wert zum key wird über die Funktion valueForKey aus dem NSDictionary geholt.

Eine weitere Möglichkeit ein NSDictionary zu erzeugen ist die Funktion dictionaryWithObjectsAndKeys. Diese wird im folgenden Beispiel vorgestellt.

void dictionaryTest2() {
	NSLog(@"dictionaryTest2");

	//Create dictionatry with keys and values
	NSDictionary* aDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"MacBook 13.3 white",@"1001",@"iPod 8GB",@"1002", @"iPhone 16GB", @"1003", nil];

	//Print all key-value pairs of the dictionary using the for..in (NSFastEnumeration). Available since 10.5
	id aKey;
	for (aKey in aDictionary) {
		NSLog(@"%@ = %@", aKey, [aDictionary objectForKey:aKey]);
	}
}

Hier ist bei der Erzeugung zu sehen, daß die Schlüssel und die Werte direkt an die Funktion dictionaryWithObjectsAndKeys übergeben werden. Die Parameter-Liste wird, wie bei NSArray, durch ein nil abgeschlossen. Die Ausgabe des NSDictionary wird diesmal mit einer for..in-Schleife gemacht. Diese Funktionalität steht allerdings erst ab der Version 10.5 von MacOS X zur Verfügung.

Wenn man beide Funktionen nacheinander ausführt, dann erhält man folgendes Ergebnis auf der Konsole:

008-06-11 17:59:55.460 ContainerTest[53696:10b] dictionaryTest
2008-06-11 17:59:55.464 ContainerTest[53696:10b] 1001 = MacBook 13.3 white
2008-06-11 17:59:55.477 ContainerTest[53696:10b] 1003 = iPhone 16GB
2008-06-11 17:59:55.478 ContainerTest[53696:10b] 1002 = iPod 8GB
2008-06-11 17:59:55.479 ContainerTest[53696:10b] dictionaryTest2
2008-06-11 17:59:55.480 ContainerTest[53696:10b] 1001 = MacBook 13.3 white
2008-06-11 17:59:55.480 ContainerTest[53696:10b] 1003 = iPhone 16GB
2008-06-11 17:59:55.481 ContainerTest[53696:10b] 1002 = iPod 8GB

In beiden Beispielen werden die NSDictionarys direkt bei der Erzeugung mit Werten belegt. Ein späteres Hinzufügen oder Löschen von Elementen ist nicht möglich. Deshalb gibt es die Klasse NSMutableDictionary, die es ermöglicht Änderungen an dem Dictionary vorzunehmen. Das Folgende Beispiel zeigt wie das geht.

void dictionaryMutableTest() {
	NSLog(@"dictionaryMutableTest");

	//Creates an empty dictionary
	NSMutableDictionary* aDictionary = [NSMutableDictionary dictionary];

	//Add three entries
	[aDictionary setObject:@"MacBook 13.3 white" forKey:@"1001"];
	[aDictionary setObject:@"iPod 8GB" forKey:@"1002"];
	[aDictionary setObject:@"iPhone 16GB" forKey:@"1003"];
	printDictionary(aDictionary);

	//Remove the old iPhone
	[aDictionary removeObjectForKey:@"1003"];
	printDictionary(aDictionary);

	//Add the new iPhone
	[aDictionary setObject:@"iPhone 3G 16GB" forKey:@"1004"];
	printDictionary(aDictionary);
}

Als erstes wird ein leeres Dictionary erzeugt. Dann werden drei Einträge mit der Methode setObject hinzugefügt. Als nächstes wird ein Eintrag mit der Funktion removeObjectForKey entfernt. Als Parameter wird einfach die Schlüssel übergeben. Danach wird nochmals ein neuer Eintrag ergänzt. Nach jeder Aktion wird der Inhalt des NSMutableDictionary mit der Funktion printDictionary jeweils ausgegeben. Diese Funktion benutzt die For..in-Schleife.

void printDictionary(NSDictionary* aDictionary) {
	NSLog(@"=======================================");
	id aKey;
	for (aKey in aDictionary) {
		NSLog(@"%@ = %@", aKey, [aDictionary objectForKey:aKey]);
	}
}

Die Ausgabe der Funktion ist im Folgenden zu sehen:

2008-06-11 17:59:55.482 ContainerTest[53696:10b] dictionaryMutableTest
2008-06-11 17:59:55.483 ContainerTest[53696:10b] =======================================
2008-06-11 17:59:55.483 ContainerTest[53696:10b] 1001 = MacBook 13.3 white
2008-06-11 17:59:55.490 ContainerTest[53696:10b] 1003 = iPhone 16GB
2008-06-11 17:59:55.491 ContainerTest[53696:10b] 1002 = iPod 8GB
2008-06-11 17:59:55.492 ContainerTest[53696:10b] =======================================
2008-06-11 17:59:55.497 ContainerTest[53696:10b] 1001 = MacBook 13.3 white
2008-06-11 17:59:55.498 ContainerTest[53696:10b] 1002 = iPod 8GB
2008-06-11 17:59:55.517 ContainerTest[53696:10b] =======================================
2008-06-11 17:59:55.518 ContainerTest[53696:10b] 1001 = MacBook 13.3 white
2008-06-11 17:59:55.518 ContainerTest[53696:10b] 1004 = iPhone 3G 16GB
2008-06-11 17:59:55.519 ContainerTest[53696:10b] 1002 = iPod 8GB