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:

Soutěž

Sponzorem soutěže je:

IDIF

 

Jaký fotograf/ka získal/a cenu za nejpopulárnější příspěvek v Nikon Photo Contest?

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

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  

Diskuse k článku

 

Vložit nový příspěvek   Sbalit příspěvky

 

deklarace

Autor: hroch32 Muž

Založeno: 04.09.2006, 08:46
Odpovědí: 0

Dotaz k tomu makru - ono je v ObjectiveC možné deklarovat proměnné v podmínce (resp. inicializaci) příkazu?

Odpovědět na příspěvek

RE: deklarace

Autor: valda Muž

Založeno: 04.09.2006, 09:22

Myslim, ze to pujde, kdyz si zapnes vyssi verzi standardu jazyka C, tedy napr. C99.

Tohle jsem vykopiroval z Xcode z informaci o teto volbe:

Choose a standard or non-standard C language dialect.

ANSI C: Accept ISO C90 and ISO C++, turning off GNU extensions that are incompatible. [-ansi]

Incompatible GNU extensions include the 'asm', 'inline', and 'typeof' keywords (but not the equivalent __asm__, __inline__, and __typeof__ forms), and the '//' syntax for comments.

This setting also enables trigraphs.

C89: Accept ISO C90, but not GNU extensions. [-std=c89]

GNU89: Accept ISO C90 and GNU extensions. [-std=gnu89]

C99: Accept ISO C99, but not GNU extensions. [-std=c99]

GNU99: Accept ISO C99 and GNU extensions. [-std=gnu99]

Compiler Default: Tells the compiler to use its default C language dialect. This is normally the best choice unless you have specific needs. (Currently equivalent to GNU89.)

Please see the full GCC manual for the full definition of all these settings on the C dialect:
per/ADC%20Reference%20Lib
rary/documentation/Develo
perTools/gcc-4.0.0/gcc/C-
Dialect-Options.html>
[G
CC_C_LANGUAGE_STANDARD]

Odpovědět na příspěvek

RE: deklarace

Autor: OC Muž

Založeno: 04.09.2006, 12:42

Jj, samozřejmě, už dost dlouho GNU Objective C umí všechna rozšíření C99, jen je třeba nastavit GNU99. Já pro for už hodně dlouho používám následující dvojici maker:

#define forall3(variable,enumerat
or,enumerable) for (id variable,enumerator=[enum
erable objectEnumerator];(variab
le=[enumerator nextObject]);)
#define forall(variable,enumerabl
e) forall3(variable,_OCS_OCS
_OCS_internal_enumerator_
,enumerable)

To první se hodí v případě, kdy potřebuji mít explicitní přístup i k samotnému enumerátoru. To samozřejmě v ObjC 2 s novou syntaxí půjde také, ale na dva řádky:

NSEnumerator *en=...;
for (type var in en) ...;

Odpovědět na příspěvek

RE: RE: deklarace

Autor: hroch32 Muž

Založeno: 04.09.2006, 12:50

Díky oběma. T

Odpovědět na příspěvek

 

 

Vložit nový příspěvek

Jméno:

Pohlaví:

,

E-mail:

Předmět:

Příspěvek:

 

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: