Wstęp
W drugiej części małego tutoriala postaram się opisać podstawy języka Objective-C, który jest głównym środowiskiem programowania na iPhonie. Apple wspierał wcześniej SDK dla Javy jednak zaprzestał na rzecz własnego języka. Nie jest to pewnie zaskoczenie, że forsują swoje rozwiązanie;)
Objective-C jest rozszerzeniem języka ANSI C o możliwości programowania obiektowego. Zatem dostajemy dziedziczenie, enkapsulacje czy polimorfizm. Symbole [] oraz @ są podstawą rozszerzenia Objective-C. Zmian jest trochę więcej ale o nich poniżej.
Składnia
ID
Ważnym nowym składnikiem jest id
, który jest uniwersalną referencją (patrząc od strony C jest to wskaźnik) do każdego obiektu. Z tym, że referencja obiektu nil
ma wartość 0
.
Klasy
Klasy definiujemy w plikach o rozszerzeniu *.h
natomiast implementacje klasy dokonujemy w plikach o rozszerzeniu *.m
lub *.mm
dla C++. W pliku *.h
definiujemy zmienne oraz metody klasy. Poniżej składnia deklaracji klasy Motorower
dziedzicząca po podstawowej klasie NSObject
.
#import "file.h" @interface Motorower : NSObject <Motor, Rower> { int kola; id kolorostyka; NSString* marka; } - (id)zainicjalizujRowerMarki:(NSString*)nazwaMarki; + (Motorower*)stworzMojRowerZMarka:(NSString*)nazwaMarki; @end
Najważniejsze elementy deklaracji:
#import
dołącza pliki nagłówkowe dodatkowo dbając, by nie były dołączane rekurencyjnie (require_once
w PHP)- Deklaracja klasy zaczyna się dyrektywą
@interface
oraz kończy@end
- po nazwie klasy umieszczamy dwukropek i nazwę klasy nadrzędnej
- interfejsy umieszczamy po przecinku w nawiasach ostrych –
<Motor, Rower>
- Zmienne obiektu umieszczamy pomiędzy nawiasami {}
- Po bloku ze zmiennymi umieszczamy deklaracje metod (nie zapomnijcie o średniku na końcu)
Implementacja przykładowej klasy:
@implementation Rower - (id)zainicjalizujRowerMarki:(NSString *) nazwaMarki { if (self = [super init]) { kola = 0; kolorostyka = nil; marka = [nazwaMarki copy]; return self; } } + (Rower *)stworzMojRowerZMarka: (NSString *) nazwaMarki { return [[[self alloc] zainicjalizujRowerMarki:nazwaMarki] autorelease]; } @end
Cechy charakterystyczne implementacji:
- implementacja zawarta jest pomiędzy dyrektywami
@implementation
a@end
- specyficzny sposób wywoływanie metod zostanie omówione osobno
Metody
Mamy do dyspozycji metody dla instancji obiektu oraz dla klasy. Poniżej przykładowa deklaracja metody wraz z opisem:
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index // opowiednik w PHP function insertObject(id $anObject, NSUInteger $index) {}
Powyżej deklaracja metody dla instancji obiektu ( +
na początku deklaracji oznaczałby metodę klasy) insertObject
przyjmującej dwa parametry pierwszy ((id)anObject
) będący wskaźnikiem. Natomiast drugi parametr o nazwie atIndex
jest obiektem typu NSUInteger
przypisany do zmiennej wewnętrznej index
.
Podobnie jak w ruby tak i w Objective-C przyjęto koncepcje wiadomości wysyłanych do obiektów. I tak na podstawie sygnatury wybierana jest odpowiednia metoda, która powinna być wywołana w chwili wysłania wiadomości do obiektu/klasy.
[mojaTablica insertObject:obiekt atIndex:0]; //odpowiednik w PHP $mojaTablica->insertObject($obiekt, $index);
Użycie wiadomości wysłanej do klasy (nie obiektu):
NSMutableArray* myArray = nil; // // tworzenie nowej modyfikowalnej tablicy myArray = [NSMutableArray arrayWithCapacity:0]; //Odpowiednik PHP $myArray = NSMutableArray::arrayWithCapacity(0);
Wiadomość jest opisana pomiędzy nawiasami kwadratowymi []. Na początku jest napisany odbiorca następnie parametry. Można wykorzystać wyniki wiadomości jako obiekty w parametrach lub odbiorcach wiadomości np.:
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0]; // odpowiednik w PHP $myAppObject->getArray()->insertObject($myAppObject->getObjectToInsert(), 0);
Właściwości
Projektanci Objective-C w celu ograniczenia ilości getterów i setterów wprowadzili mechanizm właściwości. Dzięki temu możemy uniknąc tworzenia trywialnych getterów/setterów tworząc je poprzez deklaracje kompilatora. Tym samym zmniejszamy redundancje kodu przenosząc pracę na kompilator.
Właściwości definiuje się w bloku definiowania metod pliku nagłówkowego klasy (pliki *.h
po nawiasie }
a przed dyrektywą @end
). Właściwości można definiować z pewnymi opcjami, poniżej przykłady:
@property BOOL flag; @property (copy) NSString* nameObject; // Kopiuje obiekt w czasie przypisania @property (readonly) UIView* rootView; // Tworzy tylko gettera
Dodatkową zaletą właściwości jest możliwość używania notacji z kropką np.:
mojObiekt.flaga = YES; CGRect ramka = mojObiekt.widok.ramka; //Zamiast notacji [mojObiekt setFlaga:YES]; CGRect ramka = [[mojObiekt widok] ramka];
Lista atrybutów właściwości
readonly - tylko getter
readwrite
– zarówno getter jak i setter – domyślny atrybutassign
– proste przypisywanie wartości – domyślneretain
– opcja, która umożliwia zapobieganie realokacji właściwości przez garbage collectora bez twojego pozwolenia (tylko obiekty Objective-C)copy
– przypisywanie wartości poprzez kopiowanie stanu obiektunonatomic
– opcja ta w odwrotności do domyślnejatomic
nie gwarantuje otrzymania wartości w procesie atomowym w czasie pobierania/zapisywania co może mieć znaczenie przy pracy wielowątkowej
Źródła
W następnym odcinku
W kolejnej części opisze jak uruchomić najprostszą aplikację czyli od stworzenia projektu po uruchomienie na iPhonie (ze złamanymi zabezpieczeniami).
Najnowsze komentarze