Objective C 2.0 - novinky z Leoparda - 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:

Seriály

Více seriálů



Software

Objective C 2.0 - novinky z Leoparda

4. září 2006, 00.00 | Vzhledem k tomu, že se začínají objevovat informace o novinkách, jež najdou programátoři příští rok v operačním systému Mac OS X 10.5 Leopard, je možná vhodná chvíle podívat se na ně trochu blíže i zde. V dnešním článku se podíváme na jednu z "nejžhavějších" novinek – rozšíření a doplňky programovacího jazyka Objective C.

Vzhledem k tomu, že se začínají objevovat informace o novinkách, jež najdou programátoři příští rok v operačním systému Mac OS X 10.5 Leopard, je možná vhodná chvíle podívat se na ně trochu blíže i zde. V dnešním článku se podíváme na jednu z "nejžhavějších" novinek – rozšíření a doplňky programovacího jazyka Objective C.

Objective C se v podstatě neměnilo již předlouhou řadu let: jazyk, v němž programujeme aplikace v Tigeru, je v podstatě přesně týmž jazykem, v němž byly psány aplikace pro prvé verse NeXTStepu před bezmála dvaceti lety. Na jednu stranu to samozřejmě je především dokladem toho, jak byl jazyk Objective C dobře navržen; na straně druhé však patrně po takové době určitě bude drobnost nebo dvě, jež je vhodné do jazyka přidat.

Jen pro úplnost: výjimky a synchronizace

Ačkoli, jak jsme si řekli, jazyk Objective C zůstal v podstatě stejný, přece jen nějaká drobná rozšíření již obsahuje dnes, v Tigeru; my jsme o nich již mluvili, a proto si je jen ve stručnosti připomeneme:

  • jazyková podpora výjimek nabízí s využitím direktiv @try/@catch/@finally/@throw mechanismus výjimek velmi podobný tomu, s nímž se setkáme kupříkladu v Javě. "Nové" výjimky mají oproti "starým" některé výhody; asi nevýznamnější bude větší pohodlí dané možností užívat několik různých direktiv @catch, z nichž každá zachytává výjimky jiné třídy, spolu s bezpečností danou tím, že překladač může korektně zpracovat příkazy goto či return uvnitř chráněného bloku. Důležité také je to, že "nové" výjimky jsou plně kompatibilní se "starými" (representovanými makry NS_DURING/NS_HANDLER/NS_ENDHANDLER).
  • Podobně synchronizace může být realizována na úrovni jazyka s použitím direktivy @synchronize. I tato možnost je zpětně kompatibilní s "klasickou" synchronizací založenou na třídách NS*Lock.

Leopardí novinky

Zatímco výše zmíněné direktivy pro práci s výjimkami a pro synchronizaci jsou již součástí stávajícího překladače, novinky popsané níže budou k dispozici až v Leopardu.

Samozřejmě tedy jde o popis předběžný a bez záruky: informace, uvedené níže, jsou kombinací veřejných zdrojů (převážně CocoaDev, několika různých diskusních klubů, a úryvků kódu psaného v Objective C 2.0, jež lze najít prostřednictvím Google) a také kvalifikovaného odhadu, založeného na tom, co je o vývojovém prostředí Cocoa známo nyní. Je ovšem stále možné, že ten či onen detail bude v cílové podobě Mac OS X 10.5 vypadat malinko jinak!

64 bitů

Runtime Objective C i knihovny Cocoa v Leopardu zřejmě mohou běžet v plnohodnotném čtyřiašedesátibitovém režimu. Z hlediska většiny běžných aplikací je to lhostejné; významné to však může být u aplikací extrémně náročných na adresový prostor. Ty až dosud musely být psány jako čtyřiašedesátibitové jádro v plain C, a druhý (dvaatřicetibitový) tásk, obsahující grafické uživatelské rozhraní, v Cocoa.

Garbage collector

Objective C – či lépe řečeno Cocoa, neboť zde se samozřejmě jedná o službu, jež není dána čistě rozšířením jazyka, ale vhodnou spoluprací mezi překladačem a standardními knihovnami – v Leopardu nabízí plně automatický garbage collector. Jinými slovy, ti, kdo nikdy nepřišli na chuť kombinaci služeb retain/release/autorelease a autorelease poolům, se jim nadále budou moci zcela vyhnout, a nechat runtime, aby se o správu paměti staral sám.

V zásadě to znamená, že objekty podle potřeby vytváříme, a o nic jiného se nemusíme starat – garbage collector je zruší automaticky poté, kdy již na ně nebudeme mít žádný funkční odkaz. Při deklaraci odkazů také můžeme určit, zda náhodou nejde o tzv. "weak referenci" – odkaz, jenž má být garbage collectorem ignorován.

Podle informací, jež jsou veřejně k dispozici, by se mělo jednat o "chytrou" implementaci garbage collectoru, zachovávající zpětnou kompatibilitu s kódem, využívajícím "klasickou" správu paměti, založenou na autorelease poolech a počítání referencí. Pro každou aplikaci (patrně pro každý tásk, možná thread – to zatím není jisté) si také budeme moci volně vybrat, má-li v ní běžet garbage collector nebo má-li se v ní využívat klasické správy paměti.

Nepovinné metody v protokolech

Formální protokoly, deklarované pomocí direktivy @protocol, sice přinášely některé výhody, avšak v řadě případů bylo jejich použití problematické. Jedním z problémů bylo také to, že všechny metody, deklarované v protokolu, byly povinné; proto nebylo možné formální protokol použít např. pro specifikaci metod delegáta, a v takovýchto případech bylo nutné užít tzv. protokolu neformálního (kategorie třídy NSObject).

Objective C 2.0 tento problém odstraňuje: v protokolech nyní můžeme použít direktivu @optional. Jejím prostřednictvím lze deklarovat nepovinné metody – takové, jež třída implementující protokol obsahovat může, ale také nemusí.

Efektivní enumerace v cyklu for

Ačkoli pomocí maker bylo vždy možné využít služby třídy NSEnumerator k pohodlnému procházení kontejnerů – v principu šlo o příkazy typu

for (id o,en=[container objectEnumerator];o=[en nextObject];) ...

Objective C 2.0 nabízí lepší konstrukci, jež umožňuje využít proměnné libovolného typu, a jež by navíc podle dostupných informací měla být mnohem efektivnější. Výše uvedený příklad můžeme v Objective C 2.0 přepsat takto:

for (id o in container) ...

případně – známe-li typ objektů, jež jsou uloženy v kontejneru – třeba takto:

for (NSString *s in containerWithStrings) ...

Deklarace properties

To nejlepší jsme si nechali na konec: Objective C 2.0 obsahuje poměrně bohatou podporu pro deklaraci a automatickou implementaci "properties" – proměnných objektu. V nejjednodušším případě se nový přístup příliš neliší od klasického:

@interface NewClass:NSObject
@property(ivar) NSString *foo;
@end

Výše uvedená deklarace je víceméně ekvivalentní současnému

@interface OldClass:NSObject {
  NSString *foo;
}
@end

Rozdíl však spočívá v tom, že v "nové" variantě překladač přímo ví, že "foo" je property objektu; vedle přístupu prostřednictvím KVC, který máme k dispozici již nyní, a který samozřejmě bude fungovat i nadále:

NewClass *nc=...;
OldClass *oc=...;
[nc setValue:[oc valueForKey:@"foo"] forKey:@"foo"];

by při použití "nové" deklarace mělo být možné používat accessory, ačkoli jsme je explicitně nedeklarovali ani neimplementovali; accessory by nám měl překladač doplnit automaticky:

[nc setFoo:[[nc foo] lowercaseString];

a dokonce se zdá, že bychom měli mít k dispozici novou tečkovou notaci, jež – podle všeho při zachování plně dynamické funkce Objective C s pozdní vazbou – umožňuje zápis z minulého řádku zjednodušit na

nc.foo=[nc.foo lowercaseString];

Nová deklarace umožní také vyžádat si explicitně kopírování objektu. Připomeňme, že jedním z problémů s implicitním použitím KVC bylo vždy to, že při výše uvedené deklaraci třídy OldClass a pokud jsme neimplementovali žádný accessor, příkaz [oc setValue:string forKey:@"foo"] vždy uložil zadaný string do proměnné foo jako sdílený, pomocí metody retain. To mohlo vést k nepříjemným problémům v případě, že foo měl být atribut objektu, a zadaný string byl měnitelný.

Nová podpora "properties" tento problém řeší; uvedeme-li deklaraci

@property(ivar,bycopy) NSString *foocp;

pak příkaz [oc setValue:string forKey:@"foo"] – stejně jako nově použitelné ekvivalentní příkazy [oc setFoocp:string] nebo ještě jednodušší oc.foocp=string – budou fungovat stejně, jako kdybychom explicitně implementovali accessor

-(void)setFoocp:(NSString*)s {
  [foocp autorelease];
  foocp=[s copy];
}

Zdá se také, že můžeme deklarovat properties neobjektových typů, a používat je přímo bez nutnosti kódování dat do objektů třídy NSValue, jak tomu bylo dosud; bude-li tomu skutečně tak, výrazně to usnadní artimetiku – srovnejte

@interface Bar:NSObject {
  int classicint;
}
@property(ivar) newint;
@end
...
Bar *bar=...;
// classic:
NSNumber *n=[bar valueForKey:@"classicint"];
n=[NSNumber numberWithInt:[n intValue]+3];
[bar setValue:n forKey:@"classicint"];
// new:
bar.newint+=3;

Podle všeho nová syntaxe podporuje i další atributy, přinejmenším přepínač readonly, který deklaruje property již nelze nastavovat (typicky generovaný údaj), a přepínače getter a setter, jejichž prostřednictvím můžeme explicitně určit accessory, jejichž prostřednictvím se má k atributu přistupovat – těch zřejmě využijeme v případě, kdy nám jednoduché standardně generované accessory nestačí, a budeme chtít implementovat vlastní s rozšířenou funkčností.

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

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Začínáme s  

 » Rubriky  » Software  

 

 

 

Nejčtenější články
Nejlépe hodnocené články
Apple kurzy

 

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

Uživatelské jméno:

Heslo: