2011-03-08 5 views
2

Mon programme se bloque lorsque j'appelle la fonction CGContextStrokePath (dernière ligne dans le code ci-dessous). Le contexte peut-il être corrompu en quelque sorte? (Il se bloque uniquement lorsque expression (qui est un NSArray) a certaines valeurs dedans). Il est censé dessiner un graphique de tout ce qui est en expression. Par exemple, si expression a les objets: x, cos (représenté par des chaînes), il dessine une courbe en cosinus. Voici le code:CGContextRef se corrompu?

- (double) yValueFromExpression:(id)anExpression atPosition:(double)xValue 
{ 
    NSDictionary *aDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:xValue] forKey:@"%x"]; 
    return [CalculatorBrain evaluateExpression:anExpression usingVariableValues:aDictionary]; 
} 

#define PRECISION 500 

- (void)drawRect:(CGRect)rect 
{ 
    double scale = [self.delegate scaleForGraphView:self]; 
    id expression = [self.delegate expressionForGraphView:self]; 

    CGPoint origin; 
    origin.x = (self.bounds.origin.x + self.bounds.size.width)/2; 
    origin.y = (self.bounds.origin.y + self.bounds.size.height)/2; 

    [AxesDrawer drawAxesInRect:self.bounds originAtPoint:origin scale:scale]; 

    // -150/scale to 150/scale is the range of x values that axesDrawer (drawAxesInRect) displays. 
    double leftMostXValue = -150/scale; 
    double rightMostXValue = 150/scale; 
    double increment = (rightMostXValue - leftMostXValue)/PRECISION; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextBeginPath(context); 
    CGContextMoveToPoint(context, self.bounds.origin.x, origin.y - 
        [self yValueFromExpression:expression atPosition:leftMostXValue] * scale); 

    for (int i = 1; i <= PRECISION; ++i) { 
     double currentXValue = leftMostXValue + i * increment; 
     CGContextAddLineToPoint(context, self.bounds.origin.x + (self.bounds.size.width/PRECISION) * i, 
          origin.y - [self yValueFromExpression:expression atPosition:currentXValue] * scale); 
    } 
    CGContextStrokePath(context); 
} 

Voici le message d'erreur que je reçois quand CGContextStrokePath est appelé: Program received signal: “EXC_BAD_ACCESS”.

Réponse: je dois mettre un garde autour CGContextAddLineToPoint() pour vous assurer qu'il est le dessin dans les limites de la rect:

for (int i = 1; i <= PRECISION; ++i) { 
    double currentXValue = leftMostXValue + i * increment; 
    double xPoint = self.bounds.origin.x + (self.bounds.size.width/PRECISION) * i; 
    double yPoint = origin.y - [self yValueFromExpression:expression atPosition:currentXValue] * scale; 
    if (xPoint < (self.bounds.origin.x + self.bounds.size.width) && xPoint > 0 && 
     yPoint < (self.bounds.origin.y + self.bounds.size.height) && yPoint > 0) { 
     CGContextAddLineToPoint(context, xPoint, yPoint); 
    } 
} 

Répondre

1

EXC_BAD_ACCESS signifie généralement que vous avez un problème de mémoire.

Si je devais deviner, expressionForGraphView pourrait retourner des ordures parfois.

+0

L'incident se produit lorsque la fonction CGContextStrokePath est appelée. Je ne comprends pas comment cela pourrait avoir quelque chose à voir avec «l'expression». – ladookie

+1

Assurez-vous de ne dessiner que dans les limites de rect. Une fois que vous commencez à ajouter des lignes à une zone hors de votre contexte, vous risquez de piétiner une autre zone de mémoire. Connectez vos points pour vérifier. – amattn

+1

ah merci, ça l'explique. J'ai mis un garde autour de CGContextAddLineToPoint et maintenant ça marche – ladookie