Gold Task Completed, but with invalid context errors


#1

I was extremely pleased to get the gold challenge completed since for most of it I felt I was stumbling around in the dark. However despite the fact that my image looks identical to the one in the book, I noticed a bunch of errors in the output:

2013-01-20 12:24:22.437 Hypnosister[885:f803] HypnosisView became first responder
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextSetLineWidth: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextSetStrokeColorWithColor: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextAddArc: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : clip: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextSaveGState: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextSetBlendMode: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextSetAlpha: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextTranslateCTM: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextScaleCTM: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextDrawImage: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextRestoreGState: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextAddArc: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextDrawLinearGradient: invalid context 0x0
Jan 20 12:24:22 Adams-Mac-mini.local Hypnosister[885] : CGContextDrawPath: invalid context 0x0
2013-01-20 12:24:22.443 Hypnosister[885:f803] Application windows are expected to have a root view controller at the end of application launch

My solution was to create a new view as a subview to HynosisterView. Here is my subview’s DrawRect method:

  • (void)drawRect:(CGRect)rect
    {
    // Drawing code
    CGContextRef hatCtx = UIGraphicsGetCurrentContext();
    CGRect bounds = [self bounds];

    CGPoint center;
    center.x = bounds.origin.x + bounds.size.width / 2.0;
    center.y = bounds.origin.y + bounds.size.height / 2.0;

    //calc radius using C function hypot(x,y)/4
    float maxRadius = hypot(bounds.size.width,bounds.size.height) / 3.0;

    //declare thickness of drawn line
    CGContextSetLineWidth(hatCtx, 1);

    [[UIColor blackColor] setStroke];

    //add shape to the context (does not draw it)
    CGContextAddArc(hatCtx, center.x, center.y, maxRadius, 0.0, M_PI * 2.0, YES);

    //add color gradient
    CGGradientRef hatGR;
    CGColorSpaceRef hatCS = CGColorSpaceCreateDeviceRGB();
    size_t num_locations = 2;
    CGFloat locations[2] = {0.0, 1.0};
    CGFloat components[8] = {0.0, 0.0, 1.0, 0.3, //start color R, G, B, Transparency
    1.0, 1.0, 1.0, 0.2}; //end color
    hatGR = CGGradientCreateWithColorComponents(hatCS, components, locations, num_locations);
    CGPoint start, end;
    start.x = 28.0;
    start.y = 0.0;
    end.x = 28.0;
    end.y = 28.0;

    CGContextClip(hatCtx);

    //Draw the shape

    UIImage *hat = [UIImage imageNamed:@“Icon”];

    [hat drawInRect:CGRectMake(0, 0, 57, 57)];
    CGContextAddArc(hatCtx, center.x, center.y, maxRadius - 1.0, 0.0, M_PI * 2.0, YES);
    CGContextDrawLinearGradient(hatCtx, hatGR, start, end, 0);
    CGContextStrokePath(hatCtx);

}

Can someone please explain all the invalid context errors that don’t hinder compilation or running of the app.


#2

I have used your code and did not get any error messages.

You should investigate why your graphics context seems to be zero.

Log its value to prove that it is indeed zero:

- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef hatCtx = UIGraphicsGetCurrentContext();
...
NSLog (@"---> hatCtx: %p", hatCtx);
...
}

Those invalid context errors you are getting are run-time errors and thus can’t affect the compilation.


#3

Thanks ibex10. Logging it told me the code was running twice. When I looked in hypnosisterAppDelegate.m I remembered that I was manually calling drawrect just before declaring my new class as a subclass of the main view:

CGRect hatFrame = CGRectMake(0, 0, 57, 57);
BNRLogoG *hat = [[BNRLogoG alloc] initWithFrame];
[hat drawRect];
[view addSubview:hat];

As soon as I removed [hat drawRect]; the error messages disappeared, but the app still works.

Still not entirely sure why or how DrawRect is called automatically…