Druhé Objective C: různé drobnosti - 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

Druhé Objective C: různé drobnosti

14. prosince 2007, 09.00 | Dnes si popíšeme řadu drobností, z nichž žádná si nezaslouží samostatný článek: ne, že by byly nepodstatné (kupříkladu definitivní odstranění syndromu "fragile class" je snad vůbec nejvýznamnějším přínosem Objective C 2.0), ale proto, že jejich přímý dopad na jazyk jako takový je poměrně malý.

V minulém díle našeho seriálu, věnovaného vývoji aplikací v prostředí Cocoa v operačním systému Mac OS X, jsme si začali povídat o novinkách v Objective C 2.0. Dnes si popíšeme řadu drobností, z nichž žádná si nezaslouží samostatný článek: ne, že by byly nepodstatné (kupříkladu definitivní odstranění syndromu "fragile class" je snad vůbec nejvýznamnějším přínosem Objective C 2.0), ale proto, že jejich přímý dopad na jazyk jako takový je poměrně malý: zrovna v minulé závorce zmíněná změna nemění syntaxi ani trochu; jen dovoluje mnohem flexibilnější programování.

Garbage collector

Ti, kdo se nikdy nedokázali sžít se systémem správy paměti Cocoa, založeném na počítání referencí pomocí zpráv retain/release a na autorelease poolech, jistě přivítají s nadšením to, že Objective C nyní podporuje plně automatický garbage collector. Ačkoli garbage collector je samozřejmě o něco méně efektivní než původní systém správy paměti, je velmi dobře použitelný: s jeho využitím je napsáno podle informací Apple např. celé nové vývojové prostředí Xcode 3.

Volba správy paměti je individuální pro každý proces: zároveň vedle sebe tedy mohou běžet procesy, v jejichž rámci je paměť spravována tradičním způsobem, i procesy, v jejichž rámci běží garbage collector. Při sestavování spustitelného programu (v rámci Xcode v "build atributes" targetu) zvolíme, zda má podporovat garbage collector ("Required") nebo fungovat bez něj ("Unsupported"):

K dispozici je samozřejmě i varianta, v níž je možné používat kterýkoli z obou režimů správy paměti ("Supported"), jež je zapotřebí pro knihovny a zaveditelné bundles, které musí pracovat v procesech obou typů.

Z hlediska vlastního jazyka je garbage collector téměř "neviditelný"; přibyly pouze kvalifikátory __weak a __strong pro deklarování ukazatelů, jejichž obsah se automaticky uvolnit má (__weak) či nemá (__strong, a také standardní hodnota, neuvedeme-li kvalifikátor vůbec). Roli původního release tedy nyní hraje uložení hodnoty nil do odkazu (typu "strong"). Je ovšem nutné mít na paměti některé důsledky (např. to, že se nevolá dealloc; namísto něj se volá jiná metoda za podstatně odlišných podmínek); to vše ale již patří do Foundation Kit, takže se na to blíže podíváme později, až si budeme popisovat jeho novinky.

Přístupová práva k proměnným objektu

Před časem jsme si popisovali možnosti jazyka Objective C a ukázali jsme si, že nabízí tři direktivy, jež specifikují přístupová práva k proměnným objektu:

  • @private pro kód samotné třídy a žádný jiný;
  • @protected pro kód samotné třídy a jejích podtříd;
  • @public pro libovolný kód.

Objective C 2.0 nyní přidává direktivu čtvrtou, @package; ta je modifikací obecného přístupu, který zajišťuje libovolnému kódu v rámci daného executable (knihovny, frameworku, aplikace či bundle); nedovolí však přístup k proměnným kódu z jiných executables. Funguje to však pouze v čtyřiašedesátibitovém režimu, neboť ve dvaatřicetibitovém nemá dynamický linker k dispozici odpovídající prostředky.

Celkem tedy nová direktiva @package funguje

  • ve dvaatřicetibitovém módu vždy stejně jako @public;
  • ve čtyřiašedesátibitovém módu pro kód, který je v témže executable jako daná třída, také stejně jako @public;
  • ve čtyřiašedesátibitovém módu pro kód, který je v jiném executable než daná třída, stejně jako @private.

Dodatečné atributy metod a tříd

Objective C 2.0 umožňuje v rámci deklarace metod a tříd doplnit některé další atributy, přesahující možnosti předchozí verze a umožňující lepší kontrolu při překladu a spolehlivější zapouzdření (na úrovni modulů, nikoli tříd). Jedná se o následující služby, z nichž pro programátory je zvláště zajímavá poslední:

  • metody i třídy lze označit jako "deprecated", a na použití takové metody nebo třídy překladač upozorní varováním;
  • argument metody lze již na úrovni deklarace označit jako nepoužitý;
  • třídu lze označit jako "skrytou", což znamená, že (ve čtyřiašedesátibitovém prostředí) nebude vůbec viditelná pro kód v jiném executable (knihovně, frameworku, aplikaci, bundle);
  • metodu s proměnným počtem argumentů lze opatřit kontrolou, zda posledním z nich je hodnota nil.

Vzhledem k její užitečnosti si poslední variantu ukážeme na konkrétním příkladu:

iMac24% >q.m                            
#import <Cocoa/Cocoa.h>
@interface X:NSObject
-(void)x:o,... NS_REQUIRES_NIL_TERMINATION;
@end
void fnc(id o) {
  [o x:@"a",@"b",@"c"];
}
iMac24% cc -c -Wall q.m -framework Cocoa
q.m: In function 'fnc':
q.m:6: warning: missing sentinel in function call
...

Samozřejmě, že tento atribut je standardně nastaven pro všechny zprávy Cocoa, jež využívají seznamu argumentů ukončeného hodnotou nil; je zde však jeden malý podraz: ve výchozím nastavení Xcode je totiž toto varování vypnuté. Musíme je nejprve zapnout – v bloku "Build" inspektoru projektu nebo targetu zapneme varování "Typecheck Calls to printf/scanf". Pak již vše funguje, jak má:

Bezpečné změny instančních proměnných

Toto je jedna z nejsilnějších a nejdůležitějších nových vlastností Objective C 2.0, ačkoli její dopad je zatím značně omezen tím, že funguje pouze ve čtyřiašedesátibitovém režimu: díky novému mechanismu přístupu k instančním proměnným již Objective C netrpí vůbec syndromem "fragile class", jímž je tak zle sužováno vinou nedomyšleného návrhu C++.

Připomeňme, o co jde: problém "fragile class" spočívá v tom, že

  • vytvoříme nějakou knihovní třídu;
  • aplikační kód jí využije a vytvoří vlastní podtřídy;
  • v knihovně provedeme nějakou změnu, jež by podle zdravého rozumu neměla nikterak narušit kompatibilitu (např. přidáme novou instanční proměnnou; odstraníme metodu, jež nebyla nikdy využívána; změníme pořadí metod či instančních proměnných apod.);
  • a aplikace s novou knihovnou ze záhadných příčin nebude fungovat!

V C++ se tento problém týkal a týká v podstatě čehokoli. Objective C se týkal pouze v jediném směru: nebylo možné měnit instanční proměnné třídy (u knihovních tříd se proto doporučovalo přidávat několik nevyužitých instančních proměnných jako rezervu pro budoucí rozšíření).

V Objective C 2.0 je tento problém odstraněn: nová verse knihovny může instanční proměnné změnit zcela libovolně (samozřejmě s výjimkou odstranění případné proměnné @public, k níž aplikační kód přistupoval přímo; to je ovšem již případ principiálně nekompatibilní změny, podobně, jako by bylo odstranění často užívané metody), a aplikační kód bude i nadále fungovat bez nejmenších problémů.

Velmi hezké je, že díky tomuto rozšíření nyní Objective C (ve čtyřiašedesátibitovém módu) umožňuje konečně se zbavit krajně nečisté – byť dosud z technických důvodů nutné – deklarace instančních proměnných v @interface: je zřejmé, že (vyjma instančních proměnných, jež jsou veřejně přístupné) se jedná o záležitost čistě implementační, která z hlediska zapouzdření nemá v @interface vůbec co dělat a patří do implementace. Objective C 2.0 to umožňuje; je ovšem zapotřebí využít nových služeb pro deklaraci accesorů, a proto si konkrétní postup ukážeme až příště.

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: