Tömbök

BecomeAnXcoder – Tömbök

Bevezető

Időnként szükség lehet arra, hogy adatok gyűjteményét tárold. Például nézzük azt az esetet, amikor sztringek egy listájával kell dolgoznod. Meglehetősen ormótlan megoldás lenne, ha minden egyes sztringhez egy változót rendelnénk hozzá. Természetesen ennél sokkal kényelmesebb megoldás is van, ezek a tömbök.
A tömb objektumok rendezett listája (, vagy még pontosabban objektumra mutató poineterek listája). Egy tömbhöz adhatsz objektumokat, kitörölheted azokat, vagy megkérdezheted a tömböt, hogy mondja meg adott index-hez (azaz egy adott pozíción) melyik objektum van tárolva. Azt is megkérdezheted egy tömbtől, hogy hány elemet tartalmaz.
Rendszerint az elemek számolását 1-től szoktuk kezdeni. A tömbök esetében azonban az első elem indexe a 0, a másodiké az 1 és így tovább …

27 Array

Példa: egy három sztringet tartalmazó tömb

Ebben a fejezetben több példát is fogunk mutatni, amelyekből jól látható lesz, hogyan működik a 0-val kezdődő elemszámlálás.

Két osztályból származtatunk tömböket: NSArray és NSMutableArray. Ugyanúgy, mint a sztringek esetében itt is van mutable és immutable változat. Ebben a fejezetben a mutable verziót fogjuk tárgyalni.

Ezek Objective C és Cocoa specifikus tömbök. Létezik egy egyszerűbb fajtája is a tömböknek a C nyelvben (ami természetesen használható az Objective C-ben is), de ezt most nem tárgyaljuk. Most csak megemlítjük ezt arra az esetre, ha később valahol olvasol a C tömbökről és fontos, hogy megértsd, hogy ennek nincs sok köze az NSArrays, vagy az NSMutableArrays-hoz.

Egy osztály metódus

A tömbkészítés egyik lehetséges útja, ha végrehajtunk egy ilyen utasítást:

[NSMutableArray array];

Ha ezt a kódot lefuttatjuk, akkor generál és visszaad egy üres tömböt.
De … várjunk csak egy kicsit … ez a kód eléggé furcsának tűnik, nem gondolod?
Valóban itt egy osztálynevet: NSMutableArray használtunk az üzenet címzettjének megjelölésekor. Viszont idáig üzeneteket mindig példányokhoz küldtünk, nem pedig osztályokhoz. Ugye?
Nos, most ismét valami újat tanultunk: azt a tényt, hogy az Objective C-ben osztályokhoz is tudunk üzeneteket küldeni (aminek az a magyarázata, hogy az osztályok is objektumok, úgynevezett meta-osztályok példányai, de ezt a kérdést nem fogjuk tovább boncolgatni ebben a bevezető tanulmányban).

Meg kell említeni, hogy ez az objektum automatikusan kikapcsolásra kerül, amikor elkészült; ez azt jelenti, hogy hozzá lett csatolva egy NSAutoreleasePool-hoz, és be lett állítva az őt létrehozó osztály metódus által kikapcsolásra. Az osztály metódus meghívása egyenértékű a következővel:

NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];

Abban az esetben, ha azt akarod, hogy a tömb hosszabb ideig éljen mint az automatikus kikapcsolás tartama, akkor el kell küldeni egy -retain üzenet példányt.

A Cocoa dokumentációban az osztályokon hívható metódusokat úgy jelöljük, hogy egy plusz jellel (“+”) kezdjük őket a “-” jel helyett, amit a metódusok előtt már többször láttunk (péládul a 8. fejezetben [4.5]). A dokumentációban a tömb metódusra a következő leírást olvashatjuk:

array
+ (id)array

Készít és visszaad egy üres tömböt. Ez a metódus az NSArray mutable alosztályain használható.
Lásd még: + arrayWithObject:, + arrayWithObjects:

Gyakorlat

Térjünk vissza a programíráshoz. A következő program készít egy üres tömböt, elraktároz benne három sztringet és ezután kiírja a tömb elemszámát.

//[1]
#import <foundation/foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *myArray = [NSMutableArray array];
[myArray addObject:@"első sztring"];
[myArray addObject:@"második sztring"];
[myArray addObject:@"harmadik sztring"];
int count = [myArray count];
NSLog(@"Összesen %d elem van az én tömbömben", count);
[pool release];
return 0;
}

Ezt lefuttatva azt kapjuk, hogy:

Összesen 3 elem van az én tömbömben

A következő program megegyezik az előzővel azzal a kivétellel, hogy a tömb 0 indexű elemét írja ki. Ezt a sztringet az objectAtIndex: metódus segítségével kapja meg [2.13].

//[2]
#import <foundation/foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *myArray = [NSMutableArray array];
[myArray addObject:@"első sztring"];
[myArray addObject:@"második sztring"];
[myArray addObject:@"harmadik sztring"];
NSString *element = [myArray objectAtIndex:0]; // [2.13]
NSLog(@"A tömb 0 indexű eleme: %@", element);
[pool release];
return 0;
}

Futás után ezt látjuk a képernyőn:

A tömb 0 indexű eleme: első sztring

Gyakran szükség lehet arra, hogy végig vegyük egy tömb összes elemét annak érdekében, hogy valamit csináljunk velük. Ezt például egy ciklus segítségével tehetjük meg amelyik kiírja a tömb összes elemét az indexek alapján sorba véve őket:

//[3]
#import <foundation/foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *myArray = [NSMutableArray array];
[myArray addObject:@"első sztring"];
[myArray addObject:@"második sztring"];
[myArray addObject:@"harmadik sztring"];
int i;
int count;
for (i = 0, count = [myArray count]; i < count; i = i + 1)
{
NSString *element = [myArray objectAtIndex:i];
NSLog(@"A tömb %d indexű eleme: %@", i, element);
}
[pool release];
return 0;
}

A futás eredménye most ez lesz:

A tömb 0 indexű eleme: első sztring
A tömb 1 indexű eleme: második sztring
A tömb 2 indexű eleme: harmadik sztring

Természetesen a tömbök nem csak sztringeket, hanem bármilyen objektumot tartalmazhatnak.

Az NSArray és NSMutableArray osztályok további metódusokat szolgáltatnak, és csak bátorítani tudunk arra, hogy tanulmányozd ezeket a dokumentációban, annak érdekében, hogy egyre többet megtudjál a tömbökről. Ezt a fejezetet egy olyan metódus bemutatásával zárjuk, amelyik lehetővé teszi, hogy egy adott indexű tömbelemet kicseréljünk egy másik objektumra. Ennek a metódusnak a neve: replaceObjectAtIndex:withObject:.

Idáig olyan metódusokkal találkoztunk amelyek legfeljebb egy argumentummal rendelkeztek. Ez most különbözik ezektől és éppen ezért beszélünk még róla: itt most két argumentum van. Észreveheted, hogy a nevében két kettőspont is van. Az Objective C metódusai akárhány argumentummal is rendelkezhetnek. Most megmutatjuk, hogyan kell ezt a metódust használni:

//[4]
[myArray replaceObjectAtIndex:1 withObject:@"Helló"];

A metódus futtatása után az 1-es indexű objektum a @"Helló" sztring lesz. Természetesen csak egy létező indexre működik ez a metódus. Azaz a megadott indexű elem helyén már kell lennie egy tárolt objektumnak annak érdekében, hogy az objektum képes legyen azt kicserélni a küldött objektummal.

Következtetés

Láthatod, hogy az Objective C-ben a metódus nevek olyanok, mint a lyukas mondatok (kettősponttal szabdaltak). Amikor meghívsz egy metódust és a lyukakat aktuális értékekkel töltöd ki, egy értelmes “mondatot” kapsz eredményül. Ez a fajta metódus név jelölés és hívás a Smalltalk-ból lett átvéve és az egyik legnagyobb erőssége az Objective C-nek, mivel a kódot nagyon kifejezővé teszi. Amikor majd a saját metódusaidat tervezed, akkor igyekezned kell olyan nevet választani nekik, hogy amikor meghívod őket, az kifejező mondatokban történhessen. Ez olvashatóbbá teszi az Objective C kódodat, ami rendkívül fontos annak érdekében, hogy a programod könnyen továbbfejleszthető legyen.

eredeti oldal