iPhone: Úvod do Objective-C
Objective-C je jednoduchý počítačový jazyk navržený k sofistikovanému objektově orientovanému programování. Objective-C rozšiřuje standardní jazyk ANSI C o syntaxi pro definování tříd, metod a vlastností, stejně jako pro ostatní konstrukce které navádějí k dynamickým rošířením tříd. Konstrukce a syntaxe tříd jsou založené na Smalltalku, jednom z prvních objektově orientovaných programovacích jazyků.
Pkud jste už někdy programovali v objektově orientovaném jazyku předtím, pak by vám následující informace měly pomoci se naučit základní syntaxi Objective-C. Mnoho tradičních konceptů objektově orientovaného programování jako je zapouzdření, dedičnost a polymorfismus, lze najít i v Objective-C. Existuje pár významných rozdílů, ale tyto rozdíly jsou zde zdůrazněny a lze o nich najít víc podrobností jinde.
Pokud jste nikdy předtím neprogramovali v objektově orientovaném jazyce, pak byste měli mít alespoň základní znalosti konceptů spojených s tímto druhem programování předtím, než začneme. Používání objektů a objektově orientovaných konstrukcí je základem návrhu aplikací pro iPhone, a porozumění tomu jak spolu tyto koncepty fungují je velmi důležité pro tvorbu vašich aplikací. Přehled konceptů v objektově orientovaném programování lze najít v Object-Oriented Programming with Objective-C. Návrhové vzory použité v Cocoa lze najít v Cocoa Fundamentals Guide.
Pro podrobnější úvod do Objective-C a jeho syntaxe najdete v The Objective-C 2.0 Programming Language.
Objective-C: Nadstavba C
Objective-C je nadstavbou ANSI verze programovacího jazyka C a podporuje tu stejnou syntaxi jako C. Stejně jako v C kódu definujete hlavičkové soubory a zdrojové soubory pro oddělení veřejných deklarací od implementačních detailů vašeho kódu. Hlavičkové soubory Objective-C používají přípony souborů uvedené v tabulce níže.
| Přípona | Typ souboru |
|---|---|
| .h | Hlavičkový soubor. Hlavičkové soubory obsahuí deklarace tříd, typů, funkcí a konstant |
| .m | Zdrojový soubor. Tato přípona je typická pro zdrojové soubory obsahující jak Objective-C tak i C kód |
| .mm | Zdrojový soubor. Zdrojový soubor s touto příponou může obsahovat C++ kód plus Objective-C a C kód. Tuto příponu byste měli použít jen pokud se odkazujete na C++ třídy nebo určité vlastnosti Objective-C kódu. |
Když chcete zahrnout vaše hlavičkové soubory do vašeho zdrojového kódu, můžete použít standardní direktivu #include překladače, ale Objective-C nabízí lepší způsob. Direktiva #import je stejná jako direktiva #include, kromě toho že zajistí aby se jeden soubor nevložil vícekrát než jednou. Příklady napsané v Objective-C stejně jako dokumentace preferují #import a vy byste měli také.
Řetězce
Jako nadstavba C, Objective-C podporuje stejné konvence pro vytváření řetězců jako v C. Jinými slovy, jednotlivé znaky jsou uzavřeny v jednoduchých uvozovkách a řetězce znaků v dvojitých uvozovkách. Avšak většina knihoven Objective-C příliš často nepoužívá C-ovské řetězce. Místo toho si většina knihoven předává objekty NSString.
Třída NSString je třída obalující řetězce a má všechny výhody které byste mohli očekávat, včetně věstavěné správy paměti pro ukládání řetězců libovolné délky, podpory Unicode, způsob formátování pomocí printf a další. Protože se řetězce používají poměrně často, Objective-C umožňuje zkrácený zápis pro vytváření NSString objektů z konstant. K použití zkráceného zápisu stačí před normální, v dvojitých uvozovkách uzavřený řetězec napsat symbol @, jak můžete vidět v následujícím příkladu:
NSString *myString = @"My String\n"; NSString *anotherString = [NSString stringWithFormat: @"%d %s", 1, @"String"]; // Vytvoříme Objective-C řetězec z C řetězce NSString *fromCString = [NSString stringWithCString: A C string" encoding: NSASCIIStringEncoding];
Třídy
Jako ve většině objektově orientovaných jazycích, třídy v Objective-C poskytují základní konstrukcí pro zapouzdření dat a akcí které nad těmito daty operují. Objekt je jednoduše instance třídy vytvořená za běhu programu, obsahující vlastní kopi proměnných instance deklarovaných v dané třídě a ukazatele na metody dané třídy.
Specifikace třídy v Objective-C vyžaduje dvě samostatné věci: rozhraní a implementaci. Rozhraní obsahuje deklaraci třídy a definuje proměnné instance a metody spojené s třídou. Implementace obsahuje konkrétní kód pro metody třídy. Obrázek níže ukazuje syntaxi deklarace třídy pojmenované MyClass, která dědí od základní třídy NSObject. Deklarace třídy začíná vždy direktivou překladače @interface a končí direktivou @end. Následuje jméno třídy (a oddělené dvojtečkou) je jméno rodičovské třídy. Proměnné instance (nebo také členské proměnné) třídy jsou deklarovány bloku kódu který je vyznačen závorkami ({ a }). Blok s proměnnými instance následuje seznam metod deklarovaných třídou. Středník označuje konec deklarace každé proměnné instance a metody.
Výpis níže ukazuje implementaci třídy MyClass z předchozího příkladu. Podobně jako deklarace třídy, je i její implementace vyznačena dvěmi direktivami překladače, @implementation a @end. Tyto direktivy dávají překladači informaci o rozsahu kterou potřebuje aby spojil metody s jejich třídou. Definice metody musí být tudíž stejná s její deklarací v rozhraní, ovšem kromě následného bloku kódu.
@implementation MyClass - (id)initWithString:(NSString *) aName { if (self = [nil; name = [aName copy]; return self; } } + (MyClass *)createMyClassWithString: (NSString *) aName { return [[[self alloc] initWithString:aName] autorelease]; } @end
Poznámka: I když předchozí deklarace deklarovala pouze metody, mohou třídy deklarovat i vlastnosti. Více podrobností o vlastnostech najdete v sekci Vlastnosti.
Když ukládáte objekty do proměnných, vždy používáte ukazatel. Objective-C podporuje oboje slabě i silně typované proměnné obsahující objekty. Silně typované ukazatele obsahují jméno třídy v deklaraci typu. Slabě typované ukazatele používají typ id pro daný objekt. Slabě typované ukazatele se často používají pro třídy kolekcí, kde může být přesný typ objektu v kolekci neznámý. Pokud jste zvýklí používat silně typovaný jazyk, můžete být názoru že slabě typované jazyky mohou způsobovat problémy. Popravdě ale nabízí ohromnou flexibilitu a dovolují psát v Objective-C dynamičtější programy.
Následující příklad ukazuje silně i slabě typované deklarace typů třídy MyClass:
MyClass* myObject1; // Strong typing id myObject2; // Weak typing
Metody
Třída v Objective-C může deklarovat dva tyoy metod: metody instance a metody třídy. metoda instance je metoda jejíž vykonání je podmíněno instancí třídy. Jinými slovy, předtím než zavoláte metodu instance, musíte nejdřív vytvořit instanci třídy. Metody třídy oproti tomu nevyžadují vytvoření instance, ale o tom až později.
Deklarace metody sestává z identifikátoru typu metody, návratového typu, jednoho nebo více klíčových slov podpisu metody (signatury), typů parametrů a jmen. Nísledující obrázek ukazuje deklarace metody instance insertObject:atIndex:. Deklaraci předchází znaménko mínus (-), které značí že se jedná o metodu instance. Jměno metody (insertObject:atIndex:) je spojením všech klíčových slov v signatuře, včetně dvojteček. Dvojtečka deklaruje přítomnost parametru. POkud nemá metoda žádné parametry, vynechává se dvojtečka po prvním (a jediném) klíčovem slovu signatury. V tomto případě přijímá metoda dva parametry:
Když chcete volat metodu, učiníte tak "zasláním" zprávy odpovídajícímu objektu. Zprávou je v tomto případě signatura metody spolu s informací o parametrech kterou metoda potřebuje. Všechny zprávy které pošlete objektu jsou adresovány dynamicky, čili využívá se polymorfismu tříd v Objective-C. Jinými slovy, pokud podtřída definuje metodu se stejnou signaturou jako má mteda v jedné z jejích nadtříd, podtřída obdrží zprávu jako první a může se rozhodnout jestli ji přepošle (nebo ne) svému rodiči.
Zprávy jsou uzavřeny v závorkách ([ a ]). Uvnitř závorek je objekt který přijímá zprávu uveden an levé straně a zpráva samotná (spolu s jakýmikoli parametry které zpráva vyžaduje) na pravé straně. Například k zaslání zprávy insertObject:atIndex: objektu v proměnné myArray by jste použili následující syntaxi:
[myArray insertObject:anObj atIndex:0];
Abyste se vyhnuli deklarování mnoha lokálních proměnných ukládáajících mezisvýsledky, dovoluje vám Objective-C vnořovat zprávy. Návatová hodnota každé vnořené zprávy je použita jako parametr, nebo jako cíl, jiné zprávy. Například byste mohli nahradit jakoukoli z proměnných použitých v předchozím příkladu zprávou která by vrátila očekávané hodnoty. Takže pokud byste měli jiný objekt, nazvaný myAppObject, který by měl metody pro přístup k objektu pole a objekt který by vkládal prvky do tohoto pole, mohli byste přepsat předcházející příklad následujícím způsobem:
[[myAppObject getArray] insertObject:[myAppObject getObjectToInsert] atIndex:0];
I když předchozí příklady posílaly zprávy instanci třídy, lze také posílat zprávy třídě samotné. Když zprávu třídě, pak metoda kterou vyberete musí být definovaná jako metoda třídy místo metody instance. Můžete o metodách třídy přemýšlet jako o analogii (ale ne úplně přesné) k statickým členům třídy v C++.
Obvykle vužijete metod třídy jako továrních metod pro vytváření nových instancí třídy nebo k přístupu k nějaké sdílené informaci spojené s třídou. Syntaxe deklarace metody třídy je stejná jako ta metody instance, s jedinou výjimkou. Místo použití znaménka mínus jako identifikátoru typu metody použijete znaménko plus (+).
Následující příklad demonstruje použití metody třídy jako tovární metody třídy. V tomto případě je metoda arrayWithCapacity metodou třídy NSMutableArray, kterí alokuje a inicializuje novou instanci třídy a vrací ji zpět vašemu programu:
NSMutableArray* myArray = nil; // nil je v podstatě to samé jako NULL // Vytvoří nové pole a přiřadí jej proměnné myArray myArray = [NSMutableArray arrayWithCapacity:0];
Vlastnosti
Vlastnosti jsou vhodným způsobem jak nahradit deklarace přístupových metod. Vlastnosti nevytváří nové proměnné instance ve vaší třídě. Jsou jednodušše zkratkou pro definování metod které přistupují k již existujícím proměnným instance. Třídy které zveřejňují proměnné instance tak moho učinit prostřednictvím vlastností místo použití syntaxe pro gettery a settery. Třídy mohou také použít vlastnosti k vystavení "virtuálních" proměnných instance - to znamená, části dat které se počítají dynamicky a aktuálně nejsou uloženy v proměnných instance.
Prakticky řečeno, vlastnosti snižují množství opakujícího se kódu který byste museli napsat. Protože většina přístupových metod je napsána podobně, vlastnosti eliminují potřebu mít zvlášť gettry a settry pro každou proměnnou instance vystavené třídou. Místo toh jen určíte chování pomocí deklarace vlastnosti a poté se vytvoří příslušné gettry a settry založené na této deklaraci v čase překladu.
Dekarace vlastností se vkládají spolu s deklaracemi vašich metod do rozhraní vaší třídy. Základní definice používá direktivu překladače @property, následovanou typem informace a jménem vlastnosti. Můžete také vlastnost upravit dle svého, čímž definujete jak se budou chovat přístupové metody. Následující příklad ukazuje pár jednoduchých deklarací vlastností:
@property BOOL flag; @property (copy) NSString *nameObject; // Zkopíruje objekt během přiřazení @property (readonly) UIView *rootView; // Vytvoří jen getter
Dalším přínosem vlastností je že můžete použít tečkovou syntaxi pro přístup k nim, jak je vidět na kódu v následujícím příkladě:
myObject.flag = YES;
CGRect viewFrame = myObject.rootView.frame;
I když jména objektu a vlastnosti v předchozím příkladě jsou zjednoušené, demonstrují flexibiltu vlastností. Tečková syntaxe zakrývá odpovídající volání metod. Každá čitelná vlastnost je pokryta metodou se stejným jménem jako je jméno vlastnosti. Každá zapisovatelná vlastnost je pokrytá další etodou ve formě setJménoVlastnosti:, přičemž první písmeno názvu vlastnosti je velké (tyto metody jsou aktuální implementací vlastností a jsou důvodem proč můžete přidat deklarace vlastností atributů vaší třídy aniž by byly kryté proměnnými instance). K implementaci předcházejícího kódu pomocí metod místo vlastností byste použii následující kód:
[myObject setFlag: YES];
CGRect viewFrame = [[myObject rootView] frame];
Více informací o tom jak deklarovat vlastnosti ve vlastních třídách najdete sekci Vlastnosti v The Objective-C 2.0 Programming Language.
Protokoly a delegáty
Protokol deklaruje metody které mohou být implementovány jakoukoli třídou. Protokoly nejsou třídami samotnými. Jednoduše definují rozhraní které které jsou ostatní objekty povinné implementovat. Když implementujete metody protokolu v jedné z vašich tříd, říká se že vaše třída splňuje (conform) daný protokol.
V iPhone OS se protokoly často používají k implementaci delegovaných objektů. Delegovaný objekt je objekt který spoléhá, nebo spolupracuje s, jiným objektem. Nejlepším způsobem jak nahlížet na spolupráci mezi protokoly, delegáty a ostatními objekty je uvést příklad.
Třída UIApplication implementuje požadované chování aplikace. Místo nuceného rozšíření UIApplication jen aby jste dosáhli jednoduchých upozornění o současném stavu aplikace, třída UIApplication předává tato upozornění voláním specifických metod přiřazeného delegátu. Objekt který implementuje tyto metody protokolu UIApplicationDelegate může obdržet daná upozornění a poskytnout vhodnou odezvu.
Deklarace protokolu vypadá podobně jako deklarace rozhraní třídy, s těmi výjimkami že protokoly nemají rodičovskou třídu a nedefinují proměnné instance. Následující příklad ukazuje deklaraci jednoduchého protokolu s jednou metodou:
@protocol MyProtocol - (void)myProtocolMethod; @end
V případě více protokolů delegátů je přijetí protokolu jen otázkou implementace metod definovaných protokolem. Existují i protokoly které vás nutí explicitně dát najevo že daný protokol podporujete a protokoly mohou specifikovat vyžadované metody i volitelné metody. jak budete postupovat při vývoji, měli byste strávit více času učením se o protokolech a jak se používají v kapitole Protokoly v The Objective-C 2.0 Programming Language.
Kam dále
Předchozí informace byla zaměřena především na seznámení se se základy jazyka Objective-C. Témata zahrnutá v tomto úvodu odpovídají vlastnostem jazyka se kterými se setkáte nejčastěji při pročítání zbývající dokumentace. Ta neobsahuje jen vlastnosti jazyka a vřele vám doporuřujeme si ji přečíst v příručce The Objective-C 2.0 Programming Language.
iPhone, Vývojové nástroje pro iPhone OS | Dr3dweRkZ | Name of Tutorial, Name of Chapter