Domanda

I am trying to write a UIView drawRect: method that calls a helper method to draw a gradient fill with some parameters that I pass along to it:

-(void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    /* code to set up color array, position point
       for gradient drawing function goes here.... */
    [self drawGradientWithContext:ctx atPoint:centerPoint withColors:colors]; 
    CGContextRelease(ctx);
}

-(void)drawGradientWithContext:(CGContextRef)ctx atPoint:(CGPoint)centerPoint withColors:(NSArray *)colors {
    /*code to set up color spaces and gradient refs
      goes here...... */
    CGContextDrawRadialGradient(ctx, gradientRef, centerPoint, 0, centerPoint, radius, kCGGradientDrawsBeforeStartLocation); 
    // release colorspace and gradient refs here....
}

When I run this code in the simulator, it appears to work fine (everything renders properly), but I receive this error message:

Error: CGContextResetState: invalid context 0x8dcc190. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

After getting this error message, I figured that CGContextRefs simply can't be passed as function parameters, so I tried this instead:

-(void)drawRect:(CGRect)rect { 
    // code to set up color array, position point
    // for gradient drawing function goes here....
    [self drawGradientAtPoint:centerPoint withColors:colors]; 
    CGContextRelease(ctx);
}

-(void)drawGradientAtPoint:(CGPoint)centerPoint withColors:(NSArray *)colors {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //code to set up color spaces and gradient refs
    //goes here......
    CGContextDrawRadialGradient(ctx, gradientRef, centerPoint, 0, centerPoint, radius, kCGGradientDrawsBeforeStartLocation); 
    // release colorspace and gradient refs
    CGContextRelease(ctx);
}

But the same thing happens: the program appears to run fine, but the runtime complains that I've used an invalid graphics context.

Is there a correct way to delegate drawing function to helper functions, or do I have to cram all my drawing code into the drawRect function?

È stato utile?

Soluzione

Don't call CGContextRelease(ctx). You didn't create or retain the context, so it is not your responsibility to release it.

The first time you do that, you're causing the context to be deallocated prematurely. Later on, when you (or the rest of UIKit) tries to use that context, it's invalid and produces that error message. It might not crash, right now, but you're just getting lucky.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top