5

J'écris une application iPhone en Objective-C qui utilise un dessin personnalisé dans les vues et je voudrais comparer différentes révisions de mon code pour voir ce qui aide vraiment. Je prévoyais de le faire en installant une nouvelle application, en ajoutant mon code de dessin personnalisé à la méthode drawRect: de la vue, puis, dans une boucle for dans le contrôleur de vue, en envoyant [UIView setNeedsDisplay] un grand nombre de fois et en chronométrant la durée prend pour compléter. Toutefois, les appels setNeedsDisplay semblent être mis en cache, même si je l'appelle 1000 fois dans une boucle for, la méthode drawRect: est appelée une seule fois. De plus, j'ai essayé d'appeler drawRect: directement, mais j'ai besoin d'un contexte graphique pour dessiner et quand je n'utilise pas setNeedsDisplay: UIGraphicsGetCurrentContext() ne me donne pas de contexte.Benchmark UIView drawRect: méthode

Des suggestions?

Merci,

Kyle

Répondre

5

Vous pouvez référence une vue en procédant comme suit:

- (NSTimeInterval)timeTakenToDrawView:(UIView *)view count:(NSInteger)count 
{ 
    CGRect bounds = [view bounds]; 
    NSDate *startDate = [NSDate date]; 
    UIGraphicsBeginImageContext(bounds.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    NSInteger i = 0; 
    for (i = 0; i < count; i++) { 
     CGContextSaveGState(context); 
     [view drawRect:bounds]; 
     CGContextRestoreGState(context); 
    } 
    UIGraphicsEndImageContext(); 
    return [[NSDate date] timeIntervalSinceDate:startDate]; 
} 

(N'a pas essayé, mais il devrait fonctionner)

+0

Cela fonctionne parfaitement, merci. – Kyle

0

intérieur du .m de votre NSView. Évidemment, vous pourriez vouloir raccorder ceci à une interface utilisateur ou quelque chose.

- (void)awakeFromNib { 
    // Have to wait for the window to be onscreen, graphics context ready, etc 
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerFired:) userInfo:NULL repeats:NO]; 
} 


- (void)timerFired:(NSTimer *)aTimer { 
    [self lockFocus]; 

    NSDate* then = [NSDate date]; 

    int callIdx = 0; 
    for(callIdx = 0; callIdx < 1000; callIdx++) { 
     [self drawRect:[self bounds]]; 
    } 
    NSDate* now = [NSDate date]; 

    [self unlockFocus]; 

    NSLog(@"Took %f seconds", [now timeIntervalSinceDate:then]); 
} 

- (void)drawRect:(NSRect)rect { 
    [[NSColor redColor] set]; 
    NSRectFill(rect); 
} 
+0

lockFocus ne semble pas être disponible sur UIViews, aussi, j'ai besoin d'un moyen de dessiner un contexte graphique dans ma fonction drawRect: setNeedsDisplay en fournit un via UIGraphicsGetCurrentContext() mais appeler drawRect: directement ne semble pas faire la même chose. – Kyle

0

N'oubliez pas, vous pouvez également utiliser le CoreImage outil de performance et obtenir framerates si votre drawRect est souvent utilisé.

Vous pouvez également utiliser certains des outils de performance pour voir la durée de cette méthode.

0

Si vous cherchez quelque chose qui peut donner une analyse un peu plus en profondeur, j'ai un ensemble de macros que vous pouvez utiliser pour le temps de profilage ici: https://gist.github.com/952456