Implementace a použití převodu hodnot - 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

Implementace a použití převodu hodnot

7. června 2006, 00.00 | Systém vazeb Cocoa nabízí elegantní řešení s automatickým převodem hodnot prostřednictvím tzv. "Value Transformeru", jejž můžeme pro každou konkrétní vazbu určit v Interface Builderu. My už jsme se s touto možností setkali; tehdy však jsme použili jeden ze standardních systémových převodníků, kdežto dnes se naučíme si psát převodníky vlastní.

V předcházejícím dílu jsme si hráli se základními vazbami – prozatím si stále vystačíme se zcela triviálním modelovým objektem, který obsahuje pouze dvojici atributů "width" a "height", a s jednoduchým kontrolérem NSObjectController; na bohatší služby dalších kontrolérů si ještě chvilku počkáme.

Převod hodnot

Minule jsme kromě jiného vytvořili pomocný panel, jehož velikost se automaticky mění tak, aby průběžně ilustrovala hodnoty atributů "width" a "height"; zmínili jsme se ovšem, že by bylo hezčí takový panel zobrazovat ve velikosti určené v milimetrech namísto v tiskařských bodech (v nichž je standardně kalibrován grafický systém Cocoa).

Jistěže bychom mohli přidat do modelu odvozené atributy "widthMm" a "heightMm"; bylo by to ale dost práce (nesměli bychom kupříkladu zapomenout na správné nastavení setKeys:triggerChangeNotificationsForDependentKey: při inicializaci). Systém vazeb Cocoa nabízí elegantnější řešení s automatickým převodem hodnot prostřednictvím tzv. "Value Transformeru", jejž můžeme pro každou konkrétní vazbu určit v Interface Builderu. My už jsme se s touto možností setkali při nastavování indikace nuly pomocí vazby "hidden"; tehdy však jsme použili jeden ze standardních systémových převodníků, kdežto dnes se naučíme si psát převodníky vlastní.

Implementace převodníku

Implementace převodníku hodnot je velmi jednoduchá: prostě vytvoříme vlastní implementaci podtřídy NSValueTransformer a v ní implementujeme dvě či tři standardní metody. My si implementujeme velmi jednoduchý MultiplyingTransformer, který dokáže převádět čísla vynásobením libovolným faktorem.

Přidáme tedy do projektu soubory "MultiplyingTransformer.h" a "MultiplyingTransformer.m". Rozhraní je triviální, a obsahuje pouze jednu proměnnou určující násobicí faktor, a deklaraci třídní zprávy pro vytvoření nové instance:

@interface MultiplyingTransformer:NSValueTransformer {
  float factor;
}
+(MultiplyingTransformer*)transformerWithFactor:(float)f;
@end

Ani implementace není příliš složitá; ukážeme si její metody postupně, abychom si mohli průběžně vysvětlit jejich význam:

@implementation MultiplyingTransformer
+(Class)transformedValueClass {
  return [NSNumber class];
}
+(BOOL)allowsReverseTransformation {
  return YES;
}
...

Prvé dvě metody jen určují schopnosti převodníku: metoda transformedValueClass vrátí třídu, jejíž hodnoty převodník vytváří; v našem případě samozřejmě půjde o číslo. Metoda allowsReverseTransformation dá systému na vědomí, zda převodník dokáže fungovat pouze v jednom směru (takže je použitelný pouze pro vazby, jež hodnotu odpovídajícího atributu čtou, ale nemění), nebo v obou – náš převodník bude ovšem obousměrný.

...
-transformedValue:value {
  return [NSNumber numberWithFloat:value?[value floatValue]*factor:0];
}
-reverseTransformedValue:value {
  return [NSNumber numberWithFloat:value?[value floatValue]/factor:0];
}
...

Vlastní převody, tj. skutečná implementace převodníku – v našem případě samozřejmě směšně jednoduchá.

Povšimněte si explicitního testu na nulovou hodnotu vstupního argumentu: to proto, že sice můžeme bezpečně kdykoli posílat libovolné zprávy hodnotě nil, ale nemůžeme použít výsledek takového výrazu, pokud by měl neceločíselnou hodnotu. Jinými slovy, zprávu floatValue hodnotě nil posílat nelze (přesně řečeno, lze, ale museli bychom ignorovat vrácenou hodnotu, takže to nemá smysl).

Instalace převodníku

Tím jsme vlastně hotovi; zbývá jen dvojice zcela standardních metod pro vytvoření instance:

...
-initWithFactor:(float)f {
  if (self=[super init]) factor=f;
  return self;
}
+(MultiplyingTransformer*)transformerWithFactor:(float)f {
  return [[[self alloc] initWithFactor:f] autorelease];
}
...

Konečně docela poslední metoda zde vlastně nemá co dělat: za normálních okolností vytváříme a registrujeme převodníky při inicializaci aplikačního kontroléru. V našem triviálním příkladu ovšem aplikační kontrolér nemáme, a vytvářet jej jen a jenom kvůli instalaci převodníku nestojí za to; proto použijeme jiný hezký trik runtime Objective C, o němž jsme se dosud nezmínili – metodu load.

Třídní metoda load je tak trochu specialita: runtime ji totiž automaticky pro každou třídu zavolá ve chvíli, kdy je daná třída zavedena do paměti – tedy velice brzy, rozhodně daleko dříve, než se provede běžný aplikační kód. Jedním z důsledků tohoto faktu je také to, že v době, kdy jsou volány metody load, ještě neexistuje autorelease pool – musíme pro metodu vytvořit její vlastní:

+(void)load {
  NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
  [self setValueTransformer:[self transformerWithFactor:72./25.4]
    forName:@"Mm2Pt"];
  [pool release];
}
@end

Významná je zde samozřejmě zpráva setValueTransformer:forName: – ta zaregistruje převodník, který je jejím prvním argumentem, pod zadaným jménem; pomocí tohoto jména se pak na něj můžeme odkazovat v Interface Builderu.

Použití převodníku

Zbytek již je zcela triviální: stačí v patřičném textovém poli určit jméno požadovaného převodníku:

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

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » 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: