ladookie
ladookie

Reputation: 1371

CGContextRef getting corrupted?

My program is crashing when I call the function CGContextStrokePath (last line in the code below.) Can context get corrupted somehow? (it only crashes when expression (which is an NSArray) has certain values in it). It's supposed to draw a graph of whatever is in expression. For example if expression has the objects: x, cos (represented as strings) it will draw a cosine curve. Here is the code:

- (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);
}

This is the error message I get when CGContextStrokePath is called: Program received signal: “EXC_BAD_ACCESS”.

Answer: I need to put a guard around CGContextAddLineToPoint() to make sure it is drawing within the bounds of the 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);
    }
}

Upvotes: 2

Views: 556

Answers (1)

amattn
amattn

Reputation: 10065

EXC_BAD_ACCESS usually means you have a memory problem.

If I had to guess, expressionForGraphView might be returning garbage sometimes.

Upvotes: 1

Related Questions