ZpětObsahDalší

Objective C: příklad 8
Statický přístup k objektům


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ětObsahDalší

Copyright (c) Chip, O. Čada 2000