24.09.2012
NSArray und NSMutableArray
In diesem Artikel werden die Klassen NSArray
und NSMutableArray
kurz beschrieben. Außerdem wird die Anwendung einiger weniger ausgewählter Funktionen demonstriert. Unter anderem wird erklärt, wie sich ein Array
mit einfachen Mitteln sortieren läßt.
NSArray erstellen
Die folgende Funktion zeigt die Verwendung eines NSArray
.
void arrayTest() { //Declare NSArray NSArray* array; //Declare NSNumber NSNumber* number; //Alloc and init NSNumber with 42 number = [[NSNumber alloc]initWithInt:42]; //Alloc and init NSArray with a NSNumber and a NSString array = [[NSArray alloc]initWithObjects: number, @"Arthur Dent", nil]; //Print the content of the array print(array); }
Als erstes wird eine Variable array
deklariert. Danach wird eine Variable number
deklariert, allokiert und mit 42
initialisiert. Dann wird das array
allokiert und mit Objekten number
und Arthur Dent
initialisiert. Abließend wird ein nil übergeben, um das Ende des Arrays zu signalisieren. Mit print
werden die Elemente des array
s auf der Konsole ausgegeben.
Ausgabe eines NSArray
Die Funktion print
sieht folgendermaßen aus:
void print(NSObject* aCollection) { //Declare a NSEnumerator NSEnumerator* aEnum; //Declare an object id object; //Get an enumerator aEnum = [aCollection objectEnumerator]; //Iterate while there is a next object while( (object = [aEnum nextObject]) ) { //Print object NSLog(@"%@",object); } }
Die Print-Funktion erzeugt einen Enumerator
indem die Nachricht objectEnumerator
an die Collection geschickt wird. Da NSArray
von NSObject
erbt, ist die Parameterübergabe an die print-Funktion richtig. Obwohl die Klasse NSObject
keine Funktion objectEnumerator
besitzt, kommt die Nachricht bei der Klasse NSArray
an.
Der Enumerator
wird verwendet, um in der while
-Schleife über die Collection zu iterieren. Bei jedem Schleifendurchlauf wird der Wert des Element ausgegeben.
NSMutableArray erstellen
Wie in dem Beispiels zu sehen ist, müssen die Werte innerhalb des Arrays während der Initialisierung übergeben werden. Sie können danach nicht mehr verändert werden. (Die Objekte selbst schon, aber nicht die innerhalb des Arrays.). D.h. es können keine Elemente gelöscht oder hinzugefügt werden. Abhilfe schafft die Klasse NSMutableArray
, die im Folgenden erklärt wird.
void arrayMutableTest() { //Declare NSMutableArray NSMutableArray* array; //Allocate and init the NSMutableArray array = [[NSMutableArray alloc] init]; //Declare NSNumber NSNumber* number; //Alloc and init NSNumber with 42 number = [[NSNumber alloc]initWithInt:42]; //Insert a NSNumber at index 0 [array insertObject:number atIndex:0]; //Insert a NSString at the end of the array [array insertObject:@"Arthur Dent" atIndex:[array count]]; //Print the content of the array print(array); }
In dieser Methode wird ein NSMutableArray
deklariert, allokiert und initialisiert. Dieses Array enthält zu Beginn keine Elemente. Dann wird wieder ein Objekt vom Typ NSNumber
erzeugt und an der ersten Position (Index 0) eingefügt. Als nächstes wird ein NSString
am Ende eingefügt. Dafür wird die Funktion count
des Arrays aufgerufen um den maximalen Index zu bestimmen. Dann wird das Array auf der Konsole ausgegeben. Da NSMutableArray
von NSArray
erbt, kann die gleiche print-Funktion, wie schon in der Methode arrayTest
, verwendet werden.
Die Ausgabe auf der Konsole sieht folgendermaßen aus:
2008-06-10 20:11:32.519 ContainerTest[51835:10b] 42 2008-06-10 20:11:32.522 ContainerTest[51835:10b] Arthur Dent 2008-06-10 20:11:32.522 ContainerTest[51835:10b] 42 2008-06-10 20:11:32.522 ContainerTest[51835:10b] Arthur Dent
Sortieren eines NSMutableArray
Um das Sortieren etwas spannender zu machen, erstellen wir eine Klasse Person
mit den Properties personname
, personfirstname
und personbirthday
. So haben wir später die Möglichkeit das NSArray
nach jedem dieser Properties zu sortieren.
Die Header-Datei der Person
sieht folgendermaßen aus:
// // Person.h // NSArraySortieren // // Created by Jörn Hameister on 24.09.12. // Copyright 2012 http://www.hameister.de . All rights reserved. // #import <Foundation/Foundation.h> @interface Person : NSObject { } @property (assign, nonatomic) NSString* personname; @property (assign, nonatomic) NSString* personfirstname; @property (assign, nonatomic) NSDate* personbirthdate; @end
Die Implementierung der Klasse ist auch nicht sehr kompliziert:
// // Person.m // NSArraySortieren // // Created by Jörn Hameister on 24.09.12. // Copyright 2012 http://www.hameister.de . All rights reserved. // #import "Person.h" @implementation Person @synthesize personname = _personname; @synthesize personfirstname = _personfirstname; @synthesize personbirthdate = _personbirthday; -(NSString*) description { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"dd.MM.yyyy"]; return [[NSString alloc] initWithFormat:@"%@ %@ %@", _personfirstname, _personname, [dateFormatter stringFromDate:_personbirthday]]; } @end
Die Methode description
wurde überladen, damit wir eine formatierte Ausgabe erhalten. Weitere Informationen zum NSDateFormatter
findet man hier: Datum und Zeit.
Als nächstes legen wir uns ein NSMutableArray
mit ein paar Person an:
NSMutableArray* persons = [[NSMutableArray alloc]init]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"dd.MM.yyyy"]; Person *person1 = [[Person alloc]init]; person1.personfirstname = @"Hugo"; person1.personname = @"Schwidnitzer"; person1.personbirthdate = [dateFormatter dateFromString:@"01.01.1970"]; Person *person2 = [[Person alloc]init]; person2.personfirstname = @"Donald"; person2.personname = @"Duck"; person2.personbirthdate = [dateFormatter dateFromString:@"20.02.1974"]; Person *person3 = [[Person alloc]init]; person3.personfirstname = @"Bart"; person3.personname = @"Simpson"; person3.personbirthdate = [dateFormatter dateFromString:@"24.06.1950"]; [persons addObject:person1]; [persons addObject:person2]; [persons addObject:person3]; NSLog(@"Unsortierte Personen: %@", persons);
Zum Sortieren nach dem Vornamen kann folgender Codeschnipsel verwendet werden:
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"personfirstname" ascending:YES]; NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; NSArray *sortedPersons = [persons sortedArrayUsingDescriptors:sortDescriptors]; NSLog(@"%@", sortedPersons);
Es ist anzumerken, dass der Aufruf eigentlich ein Einzeiler ist. Zu Verständnis ist die verhergehende Variante allerdings besser geeignet:
//Sort the NSArray with personfirstname NSArray *sortedPersons = [persons sortedArrayUsingDescriptors: [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"personfirstname" ascending:YES]] ]; NSLog(@"Nach Vornamen sortiert: %@", sortedPersons);
Soll nun nach dem Geburtsdate sortiert werden, ist folgende Anpassung notwendig:
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"personbirthdate" ascending:YES]; NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; NSArray *sortedPersons = [persons sortedArrayUsingDescriptors:sortDescriptors]; NSLog(@"Nach Geburtsdatum sortiert: %@", sortedPersons);
Als Ausgabe auf der Konsole erhält man folgende Werte: (unsortiert, nach Vornamen sortiert, nach Geburtsdatum sortiert)
2012-09-24 14:07:06.354 NSArraySortieren[1229:903] Unsortierte Personen: ( "Hugo Schwidnitzer 01.01.1970", "Donald Duck 20.02.1974", "Bart Simpson 24.06.1950" ) 2012-09-24 14:07:06.357 NSArraySortieren[1229:903] Nach Vornamen sortiert: ( "Bart Simpson 24.06.1950", "Donald Duck 20.02.1974", "Hugo Schwidnitzer 01.01.1970" ) 2012-09-24 14:07:06.359 NSArraySortieren[1229:903] Nach Geburtsdatum sortiert: ( "Bart Simpson 24.06.1950", "Hugo Schwidnitzer 01.01.1970", "Donald Duck 20.02.1974" )
Eine weitere Möglichkeit ein NSArray
zu sortieren, sind Blocks, die seit 10.6 verfügbar sind. Der folgende Code-Schnipsel zeigt ein Beispiel zum Sortieren nach dem Vornamen:
NSArray* sortedPersons = [persons sortedArrayUsingComparator:^NSComparisonResult(Person* p1, Person* p2) { return [[p1 personfirstname] compare:[p2 personfirstname]]; }]; NSLog(@"Nach Vornamen sortiert: %@", sortedPersons);
Das Beispiel kann leicht so angepasst werden, dass auch ein Sortieren nach Geburtstag oder Nachname möglich ist.
History
10.06.2008: Erstellt.
12.01.2011: Kleine Korrekturen.
24.09.2012: Sortieren von NSArray
s hinzugefügt.