从 drawRect 调用的方法中出现无效的 CGContext 错误

Posted

技术标签:

【中文标题】从 drawRect 调用的方法中出现无效的 CGContext 错误【英文标题】:Invalid CGContext error in methods called from drawRect 【发布时间】:2014-04-09 04:25:42 【问题描述】:

我正在尝试编写一个 UIView drawRect: 方法,该方法调用一个辅助方法来绘制渐变填充,其中包含我传递给它的一些参数:

-(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....

当我在模拟器中运行此代码时,它似乎工作正常(一切都正确呈现),但我收到以下错误消息:

错误:CGContextResetState:无效上下文 0x8dcc190。这是一个严重的错误。 此应用程序或它使用的库正在使用无效的上下文,因此 导致系统稳定性和可靠性的整体下降。这 通知是一种礼貌:请解决此问题。这将成为一个致命的错误 即将到来的更新。

收到此错误消息后,我认为 CGContextRefs 根本无法作为函数参数传递,所以我尝试了这个:

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

但同样的事情发生了:程序看起来运行良好,但运行时抱怨我使用了无效的图形上下文。

有没有一种正确的方法可以将绘图函数委托给辅助函数,还是我必须将所有绘图代码都塞进 drawRect 函数中?

【问题讨论】:

【参考方案1】:

不要打电话给CGContextRelease(ctx)。您没有创建或保留上下文,因此释放它不是您的责任。

第一次这样做时,会导致上下文过早地被释放。稍后,当您(或 UIKit 的其余部分)尝试使用该上下文时,它是无效的并产生该错误消息。它现在可能不会崩溃,但你只是走运了。

【讨论】:

以上是关于从 drawRect 调用的方法中出现无效的 CGContext 错误的主要内容,如果未能解决你的问题,请参考以下文章

对于drawRect使用,谨慎使用!

iOS drawRect的作用和调用机制

drawRect中一些方法的调用

-setNeedsDisplay 没有被调用来刷新 drawRect

iOS开发之drawRect的作用和调用机制

从 UIView 子类创建 CGImage