Druhé Objective C: atributy a accesory - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Odkud pochází fotografka Anne Erhard?

V dnešní soutěži hrajeme o:

Seriály

Více seriálů



Software

Druhé Objective C: atributy a accesory

9. dubna 2008, 09.00 | V posledním dílu našeho seriálu, věnovaném rozšíření jazyka Objective C 2.0 – následující díly, zabývající se čtyřiašedesátibitovým prostředím a službami Foundation Kitu, budou samozřejmě s jazykem úzce souviset, ale přece jen jde již o něco jiného – ukážeme si pohodlnou tečkovou notaci pro přístup k atributům objektu prostřednictvím accesorů.

Syntax Javy, ale zprávy!

Tečková notace byla zcela evidentně inspirována jazyky jako C++ či Java, v nichž je přístup k atributům díky této notaci mnohem pohodlnější, nežli odesílání zpráv v Objective C; platí se za to však krajním snížením flexibility. Designérům Objective C 2.0 se podařilo spojit výhody obou: máme k dispozici stejně pohodlný zápis, ale přitom zůstává všechna flexibilita plně objektového systému založeného na posílání zpráv.

Princip je jednoduchý. Připomeňme si krátkou ukázku použití atributů objektu deklarovaných pomocí direktivy @property (ačkoli je vhodné zdůraznit, že při "klasické" deklaraci zpráv by vše – včetně tečkové notace, již právě popisujeme, – fungovalo přesně stejně dobře):

Programmer *p=...; // ObjC 1.0
[p setSurname:@"Meyer"];
[p setName:[p surname]];
NSLog(@"%@, židák frajer",[p displayName]);
[p setIq:[p iq]+5];

V Objective C 2.0 – bez ohledu na architekturu, tato služba je k dispozici týmž způsobem ve dvaatřicetibitovém i čtyřiašedesátibitovém prostředí – můžeme přesně totéž napsat pomocí tečkové notace pohodlněji a přehledněji:

Programmer *p=...; // ObjC 2.0
p.surname=@"Meyer";
p.name=p.surname;
NSLog(@"%@, židák frajer",p.displayName);
p.iq+=5;

Je vhodné znovu zdůraznit, že jde skutečně o přesně totéž, nejen o úsek programu, jehož výsledek je stejný, nýbrž o zcela totožný kód. Kupříkladu zápis

p.surname=@"Meyer";

pošle objektu p zprávu setSurname: a předá jí argument @"Meyer"; podobně zápis p.displayName pošle objektu zprávu displayName. Asi nejzajímavější – z hlediska úsporného zápisu – příklad

p.iq+=5;

pak nejprve objektu p pošle zprávu iq, k vrácené hodnotě přičte 5, a výsledek předá opět objektu p jako argument zprávy setIq:.

Omezení

Jediným nepříliš podstatným omezením tečkové notace je to, že překladač v případě jejího použití trvá na přesné informaci o typu (ačkoli ji ve skutečnosti v této míře nepotřebuje!) Nelze tedy např. použít tečkovou notaci pro typ id, přestože explicitní použití zpráv funguje bez jakýchkoli problémů:

id pp=[[Programmer alloc] init];
pp.name=p.name; // překladač ohlásí chybu
[pp setName:[p name]]; // toto není problém

Ve většině příkladů to nikterak nevadí, neboť skoro vždy můžeme informaci o třídě explicitně uvést; nepříjemné to je v případech, kdy pracujeme s objekty zcela odlišných tříd, využívajíce polymorfismu. Kupříkladu následující kód je sice napsaný "rozumně", avšak vinou zmíněného omezení nebude fungovat:

NSArray *a=[NSArray arrayWithObjects:
  @"1",[NSNumber numberWithInt:2],nil];
for (id o in a)
  NSLog(@"%u",o.intValue); // nejde, ač správné

Trváme-li z nějakých důvodů na tečkové notaci (s variantou [o intValue] by samozřejmě žádný problém nebyl), máme na vybranou; buďto musíme užít nekorektní – ale díky polymorfismu plně funkční – deklarace na "nesprávnou" třídu:

for (NSString *o in a)
  NSLog(@"%u",o.intValue); // jde, ač nesprávné

nebo si musíme pomoci ne zcela korektní deklarací atributu na úrovni třídy NSObject (a ani pak nemůžeme použít id, neboť překladač trvá na NSObject*; ačkoli technicky vzato má pravdu – ne každý id je nutně NSObject – v praxi je to poněkud otravné):

@interface NSObject ()
@property int intValue;
@end
...
for (NSObject *o in a)
  NSLog(@"%u",o.intValue);

Cheme-li zdůraznit, že se schopnost vracet intValue netýká všech objektů, ale je omezena pouze na toto konkrétní použití, můžeme alternativně deklarovat formální protokol; je otázka, která z variant je ve skutečnosti čistší, neboť objekty samozřejmě ve skutečnosti protokolu neodpovídají...

Prasečinky, aneb takhle ne

Flexibilita tečkové notace a to, že se skutečně nejedná o nic jiného, nežli o odesílání zpráv, v principu umožňuje její využití (či spíše zneužití) pro řadu věcí, na něž skutečně není určena. Firma Apple speciálně zdůrazňuje, že není korektní využívat tečkové notace v následujících případech:

  • odeslání obecné zprávy, jež nemá s atributy objektu nic společného: o.retain; window.close; if (view.lockFocusIfCanDraw) ...;
  • konstrukce obecné zprávy tvaru setXXX:, jež opět není nastavením atributu: window.frameUsingName=@"...".

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Tipy a Triky  

 » Rubriky  » Začínáme s  

 » Rubriky  » Software  

Poslat článek

Nyní máte možnost poslat odkaz článku svým přátelům:

Váš e-mail:

(Není povinný)

E-mail adresáta:

Odkaz článku:

Vzkaz:

Kontrola:

Do spodního pole opište z obrázku 5 znaků:

Kód pro ověření

 

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: