V minulΘm dφlu jsme se seznßmili se systΘmem objekt∙ a ukßzali jsme si vÜechny zßkladnφ slu₧by jazyka Objective C. Nynφ se seznßmφme se zbytkem konstrukcφ, je₧ Objective C nabφzφ; aΦkoli ₧ßdnß z nich nenφ pro programovßnφ bezpodmφneΦn∞ nutnß. JednoduchΘ testovacφ progrßmky jste si snadno mohli vyzkouÜet u₧ s vyu₧itφm slu₧eb popsan²ch minule û dokß₧φ programßtorovi v²razn∞ usnadnit ₧ivot.
Neobjektovß rozÜφ°enφ
Jazyk Objective C je urΦen p°edevÜφm pro prßci s objekty; neobjektov²ch rozÜφ°enφ v n∞m proto mnoho nenalezneme. Ta, je₧ zde jsou, jsou vÜak velmi p°φjemnß. Prv²m z nich je mo₧nost pou₧φvat komentß° "//" stejn∞ jako v C++ (to ji₧ nep°φmo vyplynulo z p°φklad∙ v minulΘm dφlu, kde byly takovΘ komentß°e pou₧φvßny). Druh²m je standardizace typu a hodnot pro logickΘ (booleovskΘ) prom∞nnΘ: ani₧ by byl naruÜen standardnφ p°φstup jazyka C, slou₧φ jako logick² typ typ BOOL a odpovφdajφcφ hodnoty jsou YES a NO. Standardnφ headery prost∞ definujφ:
typedef int BOOL;
#define YES 1
#define NO 0
p°φpadn∞ v jazyce C ekvivalentnφ typedef enum {NO, YES} BOOL, jeho₧ v²hodou je, ₧e konstanty YES a NO jsou znßmy i na ·rovni debuggeru.
Velmi Üikovn²m rozÜφ°enφm je direktiva #import. Ta funguje tΘm∞° stejn∞ jako klasickß direktiva #include; p°ekladaΦ ale zajistφ, ₧e ka₧d² zdrojov² soubor se bude p°eklßdat nejv²Üe jednou. V Objective C si proto m∙₧eme uÜet°it nepohodlnΘ obklßdßnφ ka₧dΘho hlaviΦkovΘho souboru direktivami typu
#ifndef _STDIO_H_
#define _STDIO_H_
...
#endif
Je snad trochu spornΘ, zda mezi neobjektovß rozÜφ°enφ m∙₧eme °adit novΘ typy, hodnoty a identifikßtory: krom∞ typ∙ id a Class a hodnot nil a Nil, je₧ znßme ji₧ z minulΘho dφlu, nabφzφ Objective C nßsledujφcφ typy a hodnoty:
Typy:
SEL vnit°nφ reprezentace zprßvy
IMP metoda (p°φm² ukazatel na metodu, pou₧φvan² pro statick² p°φstup)
Identifikßtory
id self v implementaci metody reprezentuje objekt, kter² metodu zpracovßvß
id super dtto, ale jeho metody jsou vyhledßvßny v rodiΦovskΘ t°φd∞
SEL _cmd v implementaci metody reprezentuje zprßvu, je₧ metodu vyvolala
Typ SEL reprezentuje zprßvu a je definovßn jako celoΦφselnß hodnota, na kterou je zprßva intern∞ p°elo₧ena. Spolu s direktivou @selector, je₧ zprßvy p°evßdφ na tento typ, umo₧≥uje zprßvy uklßdat do prom∞nn²ch, vzßjemn∞ porovnßvat a podobn∞. Typ IMP vlastn∞ nenφ niΦφm jin²m ne₧ ukazatelem na funkci a vyu₧φvß se v t∞ch zcela v²jimeΦn²ch p°φpadech, kdy pot°ebujeme volat metodu rychleji ne₧ prost°ednictvφm mechanismu zprßv. Ukßzky praktickΘho pou₧itφ naleznete v p°φkladech na CD; totΘ₧ platφ i pro vÜechny ostatnφ konstrukce.
Poznamenejme, ₧e pro dosa₧enφ statickΘ typovΘ kontroly srovnatelnΘ s C++ nabφzφ Objective C mo₧nost pou₧φvat na mφst∞ typu id konstrukci "ukazatel na t°φdu" s v²znamem "objekt danΘ t°φdy nebo jejφho d∞dice". Je vhodnΘ zd∙raznit, ₧e jde pouze o statickou, p°ekladovou kontrolu û na v²sledn² program to nemß v∙bec ₧ßdn² vliv, ten bude fungovat stejn∞ dob°e (nebo stejn∞ Üpatn∞), jako kdybychom vÜude d∙sledn∞ pou₧φvali id.
Dφky tomu, ₧e self, super a _cmd jsou identifikßtory, a ne klφΦovß slova (jako je tomu nap°. v nedomyÜlenΘm C++), m∙₧eme je bez jak²chkoli problΘm∙ p°edefinovat; p°ekladaΦ Objective C proto bez problΘm∙ p°elo₧φ "obyΦejn² cΘΦkov²" program, ve kterΘm je pou₧ita nap°φklad prom∞nnß jmΘnem self.
P°φstup k prom∞nn²m
Prom∞nnΘ objektu mohou b²t k dispozici pouze jeho vlastnφm metodßm, nebo i metodßm vÜech jeho d∞dic∙, nebo û ve v²jimeΦn²ch p°φpadech, kdy z n∞jakΘho d∙vodu musφme rezignovat na objektovΘ programovßnφ a vyu₧φvat statickΘ programßtorskΘ techniky û mohou b²t prom∞nnΘ p°φstupnΘ z jakΘhokoli ·seku k≤du. Mo₧nosti p°φstupu k prom∞nn²m jsou urΦeny pou₧itφm jednΘ ze t°φ direktiv:
@private prom∞nnΘ jsou p°φstupnΘ pouze metodßm objektu samotnΘho;
@protected prom∞nnΘ jsou p°φstupnΘ i d∞dic∙m (tento p°φstup je standardnφ, nepou₧ijeme-li ₧ßdnou z direktiv);
@public prom∞nnΘ jsou p°φstupnΘ komukoli.
Jestli₧e z n∞jakΘho d∙vodu musφme rezignovat na objektov² p°φstup, m∙₧eme takΘ zφskat neomezen² p°φstup k prom∞nn²m kterΘhokoli objektu pomocφ direktivy @defs.
Kategorie
Primßrnφm ·Φelem kategoriφ je umo₧nit rozlo₧enφ implementace jednΘ slo₧itΘ t°φdy do n∞kolika zdrojov²ch soubor∙. Kategorie mß rozhranφ i implementaci obdobnΘ standardnφm, avÜak na mφst∞ nad°φzenΘ t°φdy je jmΘno kategorie v zßvorkßch. Kategorie samoz°ejm∞ nem∙₧e definovat vlastnφ prom∞nnΘ; mß vÜak voln² p°φstup k prom∞nn²m definovan²m v zßkladnφm rozhranφ t°φdy.
Dejme tomu, ₧e mßme nßsledujφcφ t°φdu:
@interface Xxx:Yyy
-aaa;
-bbb;
-ccc;
@end
vΦetn∞ odpovφdajφcφ implementace
@implementation Xxx
-aaa { ... }
-bbb { ... }
-ccc { ... }
@end
Pokud by pro nßs bylo z jakΘhokoli d∙vodu v²hodnΘ odd∞lit od sebe implementace t∞chto t°φ metod do samostatn²ch celk∙, mohli bychom stejn∞ dob°e pou₧φt zßkladnφ t°φdy a dvou kategoriφ û z hlediska prßce s t°φdou Xxx a jejφmi objekty by se nezm∞nilo v∙bec nic:
@interface Xxx:Yyy // zßkladnφ t°φda
-aaa;
@end
@interface Xxx (KategorieProMetoduB)
-bbb;
@end
@interface Xxx (AProMetoduCcc)
-ccc;
@end
Obdobn∞ by samoz°ejm∞ byla rozd∞lena i implementace.
Kategorie navφc umo₧≥ujφ dopl≥ovat nebo m∞nit ji₧ existujφcφ t°φdy: dejme tomu, ₧e bychom cht∞li, aby libovoln² objekt dokßzal reagovat na zprßvu where jmΘnem poΦφtaΦe, na kterΘm b∞₧φ proces, v rßmci n∞ho₧ objekt existuje. V Objective C nenφ nic jednoduÜÜφho û prost∞ implementujeme kategorii
@interface NSObject (ReportWhere)
-(NSString*)where;
@end
@implementation NSObject (ReportWhere)
-(NSString*)where
{
return [[NSProcess Info processInfo] hostName];
}
@end
Jakmile mßme kategorii hotovu, m∙₧eme novou slu₧bu zcela voln∞ pou₧φvat u kterΘhokoli objektu.
Protokoly
Protokol v zßsad∞ nenφ niΦφm jin²m ne₧ seznamem metod; pou₧φvß se jako spoleΦn² prvek pro specifikaci t°φd, kterΘ majφ mφt spoleΦnΘ metody, ale nejsou strukturßln∞ p°φbuznΘ (Φφm₧ nahrazuje implementaΦn∞ i programßtorsky obtφ₧nou vφcenßsobnou d∞diΦnost C++ v tom jedinΘm p°φpad∞, kdy m∞la jak²si smysl).
Protokol je definovßn obdobn∞ jako rozhranφ, nem∙₧e vÜak samoz°ejm∞ obsahovat prom∞nnΘ. Protokoly vÜak mohou mφt svou vlastnφ d∞diΦnost. Namφsto direktivy @interface je zde pou₧ita direktiva @protocol. KonkrΘtnφ p°φklad naleznete op∞t na CD.
Ostatnφ
Objective C nabφzφ jeÜt∞ dv∞ direktivy, @class a @encode. Prvß z nich prost∞ informuje p°ekladaΦ o existenci t°φdy danΘho jmΘna a slou₧φ pro dop°ednΘ reference:
@class Xxx;
@interface Yyy
-(Xxx*)xxx;
@end
@interface Xxx
-(Yyy*)yyy;
@end
Direktiva @encode slou₧φ pro dynamickou specifikaci typu, v praxi se vÜak tΘm∞° v∙bec nepou₧φvß (proto₧e pln∞ objektov² systΘm dynamickΘ typy vlastn∞ nepot°ebuje û namφsto nich se pou₧φvajφ objekty, je₧ si typovou informaci nesou implicitn∞ v sob∞); jejφ podrobn² popis si proto m∙₧eme odpustit.
Shrnutφ
DokonΦili jsme struΦn² popis jazyka Objective C; ti, kdo majφ jeho p°ekladaΦ k dispozici (jako GNU C je k dispozici na libovolnΘ platform∞, od Mac OS X p°es vÜechny unixovΘ varianty a₧ po DOS Φi Windows), v n∞m mohou psßt libovolnΘ testovacφ programy.
P°φÜt∞ se u₧ zaΦneme bavit o skuteΦn²ch vlastnostech prost°edφ Cocoa: ukß₧eme si mechanismus tvorby a zßniku objekt∙ a podobn∞.
Ond°ej ╚ada
Na Chip CD p°ilo₧enΘm k tomuto Φφslu Chipu je pro lepÜφ ilustraci °ada bohat∞ komentovan²ch p°φklad∙ jednoduch²ch program∙: