Sztringek

BecomeAnXcoder – Sztringek

Bevezető

Már eddig is találkoztunk néhány alapvető adattípussal: int, long, float, double, BOOL. Ezen kívül az előző fejezetben megismertük a pointereket. Sőt érintettük a sztring fogalmát is, méghozzá az NSLog() függvénnyel kapcsolatban. Ennek a függvénynek a segítségével lehetőségünk van karakterek képernyőre való kiíratására és közben még érték behelyettesítést is biztosít a %-jellel kezdődő kódrészletek számára. Ilyen volt például a %d.

//[1] 
float piValue = 3.1416; 
NSLog(@"Három példa sztringek képernyőre való kiíratására.\n"); 
NSLog(@"A pi szám közelítő értéke %10.4f.\n", piValue); 
NSLog(@"A dobókocka lapjainak száma %d.\n", 6);

Előre megfontolt szándékkal nem beszéltünk eddig a sztringekről, mint adattípusról. Az egész és lebegőpontos típusoktól eltérően a sztringek valódi objektumok, amelyek vagy az NSString, vagy pedig az NSMutableString osztályból származnak.
Ismerkedjünk meg most ezekkel az osztályokkal, kezdjük az NSString-gel.

NSString

Ismét pointerek

//[2] 
NSString *favoriteComputer; //[2.1] 
favoriteComputer = @"Mac!"; //[2.2] 
NSLog(favoriteComputer);

Valószínűleg a második utasítást érthetőnek találod, de az elsőt [2.1] nem árt egy kicsit megmagyarázni. Emlékszel arra, hogy amikor egy pointer változót deklaráltunk, akkor meg kellett adni, hogy milyen típusú változóra mutat? Emlékeztetőül megismételünk egy ilyen utasítást a 11. fejezetből [3].

//[3] 
int *y;

Itt megmagyarázzuk a fordítóprogramnak, hogy az y pointer változó egy egész típusú változó helyét mutatja meg a memóriában.

Hasonlóan, a [2.1] utasításban megmondjuk a fordítóprogramnak, hogy a favoriteComputer pointer változó egy olyan memória szeletre mutat, ahol egy NSString típusó változó található. Azért használunk pointer változót az Objective-C-ben a sztringek ábrázolására, mert az objektumokkal sohasem lehet közvetlenül műveleteket végezni, mindig csak pointereken keresztül tudjuk elérni őket.

Semmi gond, ha ez most még nem teljesen tiszta. Ami viszont fontos, az az, hogy a * jelőlés mindig az NSString, vagy az NSMutableString (vagy egy objektum) egy példányára utal.

The @ symbol

Ok, de miért jelenik meg ez a mulatságos @ jel állandóan? Nos, az Objective C a C-nyelvnek egy kiterjesztése, és az utóbbi rendelkezik néhány sajátossággal a sztringek kezelése terén. Annak érdekében, hogy ettől teljes mértékben megkülönböztessük az Objective C által használt objektum alapú sztringeket, ezt az @ jelet használjuk.

Egy új típusú sztring

Mennyiben fejlesztette tovább a C nyelvben használatos sztring fogalmát az Objective C? Nos, az Objective C-ben Unicode alapú sztringekkel találkozunk a korábbi ASCII sztringek helyett. Az Unicode-sztringek alapvetően mindenfajta nyelvben előforduló karaktereket képesek ábrázolni, mint például a kínai és ugyanígy a román abc betűit.

Gyakorlat

Természetesen a sztring karakterek deklarálása és értékadása is történhet egy lépésben [4].

//[4] 
NSString *favoriteActress = @"Julia";

A favoriteActress pointer változó a memóriának arra a szeletére mutat, ahol a “Julia” karaktereket reprezentáló objektum tárolva van.

Amint értéket adtál egy változónak, például a favoriteComputer-nek, adhatsz neki más értéket, de nem tudod változtatni magukat a karaktereket [5.7], mivel ez az NSString osztálynak egy példánya. Néhány perc és erről részletesebben is beszélünk.

//[5] 
#import  <foundation/foundation.h>
int main (int argc, const char *argv[]) 
{
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     NSString *favoriteComputer;
     favoriteComputer = @"iBook";  // [5.7]
     favoriteComputer = @"MacBook Pro";
     NSLog(@"%@", favoriteComputer);
     [pool release];
     return 0; 
}

Lefuttatva ezt a programot, az eredmény a következő lesz:

MacBook Pro

Igaz, hogy azt mondjuk, hogy ez a sztring nem változtatható, ettől függetlenül az egész sztringet bármikor kicserélhetjük egy másikra (és ezt meg is tettük).

NSMutableString

Az NSString osztály sztringjét immutable-nak nevezzük, mivel nem lehet módosítani. Ez egész pontosan azt jelenti, hogy a sztring karakterei egyenként nem módosíthatók.

Miért jó, ha nem lehet módosítani egy sztringet? Nos, egy nem módosítható sztringet az operációs rendszer könnyebben tud tárolni, ezért a program gyorsabb lehet ezáltal. Amikor Objective C programokat fogsz írni, meg fogod tapasztalni, hogy legtöbb esetben valóban nem kell módosítanod a sztringeket amiket használsz.

Természetesen vannak olyan esetek is, ahol olyan sztringekkel kell dolgoznod, amiket jó lenne módosítani. Szerencsére van egy másik osztály is, és az ezzel definiált sztringek már módosíthatóak lesznek. Ez az osztály az NSMutableString. Erről részletesen is szó lesz még ebben a fejezetben.

Gyakorlat

Először bizonyosodjunk meg arról, hogy megéretetted-e, hogy mit jelent az, hogy a sztringek objektumok. Mivel objektumok, ezért üzenet küldhető számukra. Például küldhetünk egy length (hosszúság) üzenetet [6].

//[6] 
#import  <Foundation/Foundation.h>
int main (int argc, const char * argv[]) 
{
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     int theLength;
     NSString * foo;
     foo = @"Julia!";
     theLength  = [foo length];  // [6.10]
     NSLog(@"A hosszúság %d.", theLength);
     [pool release];
     return 0; 
}

A futás eredménye:

A hosszúság 6.

A programozók előszeretettel használják a foo és bar változóneveket, amikor valamit magyaráznak. Ezek nem igazán jó nevek, mert nem eléggé beszédesek, ugyanúgy ahogy az x sem az. Azért használjuk most őket, hogy később ismerősek legyenek számodra és ne okozzon fejtőrést, ha az internetes fórumokon találkozol velük.

A [6.10]-es sorban a foo objektumnak elküldjük a length üzenetet. A length metódus az NSString osztályban a következőképpen van definiálva:

- (unsigned int)length

A címzettben levő Unicode karakterek számával tér vissza.

Lehetőség van az összes karakter kicserélésére, mindegyiknek a nagy betűs változatára [7]. Ennek érdekében egy megfelelő üzenetet kell küldeni a sztring objektumnak, ami nem más, mint az uppercaseString. Javasoljuk, hogy gyakorlásképpen ezt egyedül keresd meg a dokumentációban (ellenőrizd az NSString osztályban található metódusokat). Ennek az üzenetnek a hatására a sztring objektum készít egy új sztring objektumot ugyanazzal a tartalommal, de mindegyik karakter helyett a megfelelő nagybetű fog szerepelni.

//[7] 
#import  <Foundation/Foundation.h>
int main (int argc, const char * argv[]) 
{
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     NSString *foo, *bar;
     foo = @"Julia!";
     bar  = [foo uppercaseString];
     NSLog(@"%@ át lett konvertálva ebbe %@.", foo, bar);
     [pool release];
     return 0; 
}

A futás eredménye ez lesz:

Julia! át lett konvertálva ebbe JULIA!

Néha hasznos, ha lehetőségünk van arra, hogy módosítsuk egy sztring tartalmát ahelyett, hogy újat készítenénk. Ilyen esetben az NSMutableString osztályhoz tartozó objektummal kell reprezentálnod a sztringet. Az NSMutableString olyan metódusokat szolgáltat, amelyek segítségével meg lehet változtatni egy sztring tartalmát. Például az appendString: metódus az argumentumban átküldött sztringet hozzáfűzi a cél objektumhoz.

//[8] 
#import  <Foundation/Foundation.h>
int main (int argc, const char * argv[]) 
{
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     NSMutableString *foo;                      // [8.7]
     foo = [@"Julia!" mutableCopy];                // [8.8]
     [foo appendString:@" Boldog vagyok"];
     NSLog(@"Itt látható az eredmény: %@.",  foo);
     [pool release];
     return 0; 
}

A futás eredménye a következő lesz:

Itt látható az eredmény: Julia! Boldog vagyok.

A [8.8] sorban a mutableCopy metódus (ami az NSString osztályhoz tartozik) készít és visszaküld egy mutable sztringet az elküldött sztring tartalommal. Ezért a [8.8] sor lefutása után a foo változó egy mutable sztring objektumra mutat, ami a “Julia!” sztringet tartalmazza.

És még mindig a pointerekről!

A fejezet elején azt állítottuk, hogy az objektumokkal sohasem dolgozunk közvetlenül, mindig pointereken keresztül érjük el őket. Ezért használjuk a pointer jelet a [8.7] sorban is.
Amikor az “objektum” szót használjuk az Objective C nyelvben, akkor rendszerint ezalatt azt értjük, hogy “egy objektumra mutató pointer”. Az “objektum” szó ilyen értelemben az objektumra mutató pointer rövidítése. Annak a ténynek, hogy az objektumokat mindig pointereken keresztül használjuk, van egy fontos következménye, amit meg kell értened: ugyanannak az objektumnak, ugyanabban az időben több változó is megfeleltethető. Például a [8.7] sor elfutása után a foo változó megfelel egy objektumnak, ami a “Julia!” sztringet ábrázolja, amit a következő ábrán szemléltetünk:

25 Pointers 1

Az objektumokkal mindig pointereken keresztül dolgozunk

Most tegyük fel, hogy a foo változó értékét átadjuk a bar változónak a következő módon:

bar = foo;

Ennek a műveletnek az eredményeképpen a foo és a bar változó is ugyanarra az objektumra mutat:
26 Pointers 2

Több változót is hozzárendelhetünk ugyanahhoz az objektumhoz

Ebben az esetben, ha küldünk egy üzenetet az objektumnak a foo segítségével (azaz [foo dosomething];) ugyanazt az eredményt fogja szolgáltatni, mintha a bar segítségével tennénk ugyanezt (azaz [bar dosomething];), ahogy ezt a következő példában láthatjuk:

//[9] 
#import  <Foundation/Foundation.h>
int main (int argc, const char * argv[]) 
{
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     NSMutableString *foo = [@"Julia!" mutableCopy];
     NSMutableString *bar = foo;
     NSLog(@"foo a következő sztringre mutat: %@.",  foo);
     NSLog(@"bar a következő sztringre mutat: %@.",  bar);
     NSLog(@"\n");
     [foo appendString:@" boldog vagyok"];
     NSLog(@"foo a következő sztringre mutat: %@.",  foo);
     NSLog(@"bar a következő sztringre mutat: %@.",  bar);
     [pool release];
     return 0; 
}

A futás eredménye:

foo a következő sztringre mutat: Julia!
bar a következő sztringre mutat: Julia!
foo a következő sztringre mutat: Julia! boldog vagyok 
bar a következő sztringre mutat: Julia! boldog vagyok

Az objektum-orientált programnyelvek egyik alapvető jellemzője, hogy ugyanarra az objektumra egy időben több helyről is mutathatnak hivatkozások. Megjegyezzük, hogy ezt már a korábbi fejezetekben is használtuk, például a 8. fejezetben a MAFoo objektumra két különböző gomb objektumról is hivatkoztunk.

eredeti oldal