Druhé Objective C: kategorie a protokoly - 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ů



Informace

Druhé Objective C: kategorie a protokoly

10. ledna 2008, 11.00 | Doplňky a rozšíření jazyka Objective C ve verzi 2.0 se nevyhnuly ani kategoriím a (formálním) protokolům. Zatímco nová služba kategorií – možnost specifikovat tzv. rozšíření třídy ("extension") – je poměrně kosmetická a přináší v podstatě jen o trochu lepší překladovou kontrolu, novinka protokolů je zcela zásadní: teprve zavedením nepovinných metod se protokoly staly v praxi skutečně použitelnými.

Doplňky a rozšíření jazyka Objective C ve verzi 2.0 se nevyhnuly ani kategoriím a (formálním) protokolům. Zatímco nová služba kategorií – možnost specifikovat tzv. rozšíření třídy ("extension") – je poměrně kosmetická a přináší v podstatě jen o trochu lepší překladovou kontrolu, novinka protokolů je zcela zásadní: teprve zavedením nepovinných metod se protokoly staly v praxi skutečně použitelnými.

Rozšíření třídy

V praxi je u větších projektů naprosto běžné to, že jejich třídy nabízejí určité služby "všem" a širší rozsah možností, jakési "privátní API", pouze omezené skupině spolupracujících tříd. Až dosud jedinou možností, jak toto rozšířené API formalizovat, byla kategorie bez implementace, nějak takto:

// veřejný interface, Howler.h
@interface Howler:NSObject // public API
-(void)howl;
@end
// privátní interface, HowlerPrivate.h
@interface Howler (PrivateAPI) // Objective C 1.0
-(void)setVolume:(double)volume;
@end

Objective C 2.0 nyní nabízí formální prostředek, jemuž říká "rozšíření" ("extension") – prostě a jednoduše se jméno kategorie vynechá. Takových rozšiřujících "kategorií" samozřejmě může být libovolně mnoho, aniž by hrozil problém s tím, že se "poperou" jejich jména:

// veřejný interface, Howler.h
@interface Howler:NSObject // public API
-(void)howl;
@end
// privátní interface, HowlerPrivate.h
@interface Howler () // Objective C 2.0
-(void)setVolume:(double)volume;
@end

Výhodou nové metody je to, že překladač v tomto případě ví, že je v rámci třídy nutné implementovat všechny metody a vydá varování, pokud na implementaci metody setVolume zapomeneme. V případě výše popsané varianty s pojmenovanou kategorií z Objective C 1 to samozřejmě nebylo možné, a pokud jsme na takovou metodu zapomněli, zjistili jsme to až ve chvíli, kdy došlo k běhové chybě.

Nepovinné metody v protokolech

Formální protokoly v Objective C 1.0 měly jeden zcela zásadní nedostatek: třída, jež chtěla být s protokolem konformní, musela implementovat všechny jeho metody; už to byl značný problém z hlediska případného použití formálních protokolů pro definici zpráv, odesílaných delegátům.

Proto se využívalo tzv. neformálních protokolů – prostě kategorií třídy NSObject bez implementace, jejichž jediným účelem bylo deklarovat seznam metod. Takhle např. vypadá protokol delegáta NSTableView v Objective C 1.0:

@interface NSObject(NSTableViewDelegate)
- (void)tableView:(NSTableView *)tableView
  willDisplayCell:(id)cell
  forTableColumn:(NSTableColumn *)tableColumn
  row:(int)row;
- (BOOL)tableView:(NSTableView *)tableView
  shouldEditTableColumn:(NSTableColumn *)tableColumn
  row:(int)row;
...
@end

V Objective C 2.0 však protokoly mohou obsahovat direktivu @optional, jež označí všechny následující zprávy za nepovinné. V Leopardu by proto mohl týž protokol být deklarován následovně (zatím tomu tak není; programátoři firmy Apple prozatím na vyčištění starých deklarací neměli čas :) Nové protokoly, např. NSPrintPanelAccessorizing v nově rozšířené třídě NSPrintPanel, však již jsou deklarovány takto):

@protocol NSTableViewDelegate @optional
- (void)tableView:(NSTableView *)tableView
  willDisplayCell:(id)cell
  forTableColumn:(NSTableColumn *)tableColumn
  row:(int)row;
- (BOOL)tableView:(NSTableView *)tableView
  shouldEditTableColumn:(NSTableColumn *)tableColumn
  row:(int)row;
...
@end

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

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Začínáme s  

 » Rubriky  » Software  

 

 

 

 

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

Uživatelské jméno:

Heslo: