Zpět | Obsah | Další |
V rámci posledního z příkladů se seznámíme s podporou, kterou Objective C nabízí pro statické neobjektové programování.
Zamysleme se nejprve nad tím, jaký má smysl statické programování využívat. Na první pohled je místo statického programování tam, kde potřebujeme dosáhnout maximální paměťové a/nebo časové efektivity. Implementace objektových mechanismů je však velmi efektivní sama o sobě; operační systém Mac OS X (stejně jako jeho předchůdce NeXTStep) například s výhodou používá objektové mechanismy i pro implementaci ovladačů periferních zařízení. Zbývá tedy snad jen jediný typ programů, které má smysl psát neobjektově: viry...
// Objective C -- příklad 8
//
// příklad statického přístupu k objektům
#import <Foundation/Foundation.h>
@interface Test:NSObject
{ @public // proměnná i je k dispozici pro statický přístup
int i;
}
-(int)getI;
-(void)setI:(int)val;
@end
@implementation Test
-(int)getI {return i;}
-(void)setI:(int)val {i=val;}
@end
void main()
{
// proměnná 'x' má stejnou strukturu jako objekt třídy Test:
struct {
@defs(Test);
} x;
Test *test=[Test new];
IMP seti,geti; // implementace metod
int i;
// můžeme např. kopírovat data mezi objektem a 'stejnou' proměnnou:
[test setI:333];
memcpy(&x,test,sizeof(x));
printf("333=%d\n",x.i);
// proměnná i objektu text je deklarována po direktivě @public;
// můžeme k ní proto přistupovat přímo
#ifdef STATIC_ACCESS
for (i=0;i<1000000;i++)
test->i=test->i+1;
#else
// Objektově bychom mohli příklad přeprogramovat takto:
for (i=0;i<1000000;i++)
[test setI:[test getI]+1];
#endif
printf("%d=%d\n",test->i,[test getI]);
// chceme-li, můžeme získat ukazatel na metodu a volat ji jako funkci;
// musíme přitom jako první a druhý parametr uvést objekt, který má
// funkci zpracovat a zprávu, která se zpracovává
#ifdef STATIC_ACCESS
seti=[test methodForSelector:@selector(setI:)];
geti=[test methodForSelector:@selector(getI)];
for (i=0;i<1000000;i++)
seti(test,@selector(setI:),(int)geti(test,@selector(getI))+1);
#else
// Objektově bychom mohli příklad přeprogramovat takto:
for (i=0;i<1000000;i++)
[test setI:[test getI]+1];
#endif
printf("Hotovo (%d)\n",[test getI]);
}
// end of file
Zdrojový kód příkladu by už měl být čtenářům našeho seriálu zřejmý; namísto jeho podrobného popisu proto ukážeme konkrétní časový rozdíl mezi objektovým a neobjektovým přístupem:
83 /tmp\> cc -Wall -framework Foundation test.m -o test -DSTATIC_ACCESS
84 /tmp\> /usr/bin/time /tmp/test
333=333
1000333=1000333
Hotovo (2000333)
0.41 real 0.38 user 0.02 sys
85 /tmp\> cc -Wall -framework Foundation test.m -o test
test.m: In function `main':
test.m:26: warning: unused variable `geti'
test.m:26: warning: unused variable `seti'
86 /tmp\> /usr/bin/time /tmp/test
333=333
1000333=1000333
Hotovo (2000333)
0.89 real 0.87 user 0.02 sys
87 /tmp\>
Vidíme, že s využitím objektových technik se program, který nedělá téměř nic jiného než předávání zpráv, oproti statickému mechanismu zpomalí trochu více než dvakrát. To je ve všech běžných programech -- které samozřejmě dělají moho jiných věcí, takže zpomalení bude daleko menší -- velmi dobrá cena za všechny výhody objektového programování a pozdní vazby.
Zpět | Obsah | Další |
Copyright (c) Chip, O. Čada 2000