Objective-C PPKE-ITK 2013. 02. 14.
Objective-C bevezetés ● "Objective-C is a superset of C" ● Header: .h, osztálydeklarációk ● Implementáció: .m, osztályok implementációja ● Objective-C++: .mm ● Framework: Cocoa
Szintaxis @interface Student { int age; NSArray* lectures; NSString* name; } - (id)initWithName:(NSString*)name (int)age;
andAge:
+ (Student*)studentWithName:(NSString*) name; @end
Szintaxis Objective-C kulcsszavak @-al kezdődnek Osztálynév @interface Student { C++ 'class' megfelelője int age; NSArray* lectures; NSString* name; } - (id)initWithName:(NSString*)name andAge: (int)age;
+ (Student*)studentWithName:(NSString*) name; @end
Szintaxis Objective-C kulcsszavak @-al kezdődnek Osztálynév @interface Student { C++ 'class' megfelelője Member változók kapcsos zárójelek között. int age; Objective-C típusok prefixe: NS (NextStep) NSArray* lectures; NSString* name; } - (id)initWithName:(NSString*)name andAge: (int)age;
+ (Student*)studentWithName:(NSString*) name; @end
Metódusok szintaxisa //Deklaráció: - (id)initWithName:(NSString*)name andAge:(int)age;
Metódus név szétdarabolva!!!
Zárójelek között a metódus visszatérési értéke. Az id típus egy Objective-C objektumra mutató pointer. (Egy erősebb void*...) A - jelenti a példány metódust, a + jellel kezdődő metódusok osztálymetódusok.
Argumetumok: (típus) argumentumnév
Metódusok szintaxisa - C++ vs. Objective-C //Objective-C - (id)initWithName:(NSString*)name andAge:(int)age; //C++ id InitWithNameAndAge(NSString* name, int age);
Mire jó ez a furcsa szintaxis? ● Miért jó, hogy szét vannak darabolva a metódusnevek? ○ minden argumentum előtt szerepel olvashatóan leírva a funkciója ○ öndokumentáló a kód ○ névadási konvenciók segítik a kód megértését, olvasását ○ pár hét után hihetetlenül könnyűvé válik a kód olvasása
Metódus hívás, message passing ● Metódushívás NÉVSZERINT történik ● Bármikor bármilyen objektumra meghívhatunk egy metódust, a neve alapján ○ Ha az adott objektumnak nincs ilyen metódusa, kivételt dob ○ Futásidőben lekérdezhető, hogy adott objektum implementál-e adott metódust
● Szintaxis: ○
[image drawAtPoint:position withAttributes: attributes]; Metódus név szétdarabolva!!! Objektum, amin meghívjuk a metódust
Argumetumok
Kitekintés ● C++ dinamikus kötés ○ Virtuális metódustáblán keresztül keresi meg az adott metódust
● Objective-C dinamikus kötés ○ A névszerinti metódushívás maga a dinamikus kötés egyben
Futásidejű típusinformációk ● Selectorok ○ Egy metódus nevét tárolja ○ SEL method = selector(drawAtPoint:withAttributes:);
● Mire használjuk? ○
if ([obj respondsToSelector:method]) { //... }
● Egyéb típusinformációk (továbbiakért lsd. doksi) ○
Class c = [NSString class]; if ([obj isKindOfClass:c]) { //... }
Objektumok létrehozása ● Memóriakezelésről később lesz szó ● Konvenció: konstruktorok neve init-tel kezdődik Student *student = [[Student alloc] initWithName:@" Sheldon"]; A Student osztály lefoglal egy siezof (Student) méretű memóriaterületet, és vissza tér egy inicializálatlan objektummal Majd erre meghívjuk az initWithName: metódust, ami inicializálja az objektumot, és visszaadja azt
Beépített típusok ● NSObject ~ Java Object osztálya ○ Memória allokáció, és számos runtime szolgáltatás implementációja ○ Minden Cocoa osztály ősosztálya ○ - (NSString *)description; //Java toString()
● NSString ○ ○ ○
NSString *str = @"Hosszú, akár unicode string, árvíztűrőtükörfúrógép..."; //Stringek létrehozása más stringekből, gyakran így történik: NSString *str2 = [str stringBy...] //Például: NSString *str2 = [str stringByAppendingString :@"Masik sztring..." ];
Beépített típusok ● Number ○ Szám objektumok ○ Analógia: Java Integer és Double ○ NSNumber *five = @5; NSNumber *thirteen = @(8+5); NSNumber *pi = @3.141593;
○ Konvertálható alap típusokra, pl. intValue, doubleValue metódusokkal. Továbbiakért lásd a doksit.
● Value ○ Számtalan különböző típusra wrapper ○ Pl. rectangle, point, pointer, stb.
Beépített típusok ● Szokásos containerek ○ NSObject osztályba tartozó objektumokat tárolnak ○ Mutable+Immutable verzió
● Array ○
NSArray *array = @[@"iMac", @"iPhone", @"iPad", @" iPad Mini"];
○
NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithArray:array]; //Módosítható [mutableArray addObject:@"Apple TV"]; //Elemek lekérdezése. Mindkét hívás ugyanazt adja. NSString *mini1 = [mutableArray objectAtIndex:3]; NSString *mini2 = array[3];
Beépített típusok ● Dictionary ○ Kulcs-érték párok tárolása (Analógia: C++ std::map) ○ NSDictionary *prices = @{@"iPad" : @300, @"iPhone" :
@400,
@"iMac" : @500, @"Apple TV" : @100}; //Indexelhető NSNumber *iphonePrice = prices[@"iPhone"]; NSNumber *sameIphonePrice = [prices objectForKey:@" iPhone"];
○ Szintén létezik változtatható verziója NSMutableDictionary *mutablePrices = [[NSMutableDictionary alloc] init]; mutablePrices[@"iPhone"] = @1000; mutablePrices[@"Shitty IBM PC"] = @-1000;
Beépített típusok ● Set ○ Nincs rá literál NSSet *himym = [[NSSet alloc] initWithObjects:@" Ted", @"Robin", @"Barney", @"Marshall", @"Lily", nil];
○ Változtatható verziója NSMutableSet ○ addObject:, removeObject: metódusokkal adhatunk hozzá és vehetünk el elemeket
NSLog ● ● ● ●
Konzolra logol NSObjecteket, illetve alap típusokat tud kiírni Úgy működik mint a printf NSObjecteknek a description által visszaadott stringet írja ki
NSNumber *five = @5.0; NSString *string = @"String"; int basicSix = 6; double basicPi = 3.141592; NSArray *array = @[@"a", @"b", @"c"]; NSLog(@"This is five:%@ This is a string:%@ Six:%d PI=%f Three new lines:\n\n\n The contents of the array:%@",five, string, basicSix, basicPi, array);
Foreach ● Tárolókat foreach loop segítségével iterálhatjuk NSSet *himym = [[NSSet alloc] initWithObjects:@"Ted", @"Robin", @"Barney", @"Marshall", @"Lily", nil]; for (id obj in himym) { NSLog(@"%@", obj); } Kimenete: 2013-02-03 2013-02-03 2013-02-03 2013-02-03 2013-02-03
16:13:54.211 16:13:54.213 16:13:54.214 16:13:54.215 16:13:54.216
tmp[36512:303] tmp[36512:303] tmp[36512:303] tmp[36512:303] tmp[36512:303]
Ted Barney Marshall Lily Robin
Foreach ● NSArray, NSDictionary, NSSet illetve ezeknek a Mutable verziói járhatók be foreach looppal ● NS(Mutable)Dictionary esetében a KULCSOK sorozatát iterálja végig
Osztályok //Student.h @interface Student : NSObject { NSString* name; NSDate* dateOfBirth; } - (id)initWithName:(NSString *)name; //Setter getter a name memberhez - (void)setName:(NSString *)name; - (NSString*)name; @end
Osztályok Konstruktorok implementációja: - (id)initWithName:(NSString *)studentName { self = [super init]; //Ősosztály inicializálása if (!self) //Ha nem sikerult inicializálni return nil; [self setName:studentName]; //Egyéb inicializációk return self; //Végül saját magunkkal visszatérünk }
Propertyk ● Getterek és setterek automatikus generálása ● Különböző attribútumok: readonly, readwrite, strong, weak, atomic, nonatomic @interface Student : NSObject { } - (id)initWithName:(NSString *)studentName; @property (nonatomic, strong) NSString *name; @end
Propertyk ● Propertyk dot syntax-szal érhetők el Student* student = [[Student alloc] initWithName:@"Sheldon Cooper"]; //Értékadás student.name = @"Mr. Cooper"; //Lekérdezés NSString* someName = student.name;
● Propertyk által generált setterek/getterek kézzel felülírhatók, részletesen következő előadáson