iOS 7.0下的无效上下文0x0和系统性能下降

问题描述 投票:218回答:26

我已经阅读了很多关于这个可怕问题的搜索结果,不幸的是,每个人似乎都专注于特定的函数调用。

我的问题是我从多个函数中得到了相同的错误,我猜这些错误是从我使用的函数中调用的。

更糟糕的是,实际代码是在另一个项目中导入的自定义私有框架内,因此调试并不那么简单?

有人能指出我正确的方向吗?我有一种感觉我错误地调用某些方法或者上下文不好,但xcode的输出在这一点上并没有多大帮助。

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

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

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

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

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

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

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

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

当呈现自定义视图或其继承的类之一时,可能会发生这些错误。此时它们会多次生成,直到键盘不提供任何输入。触摸事件仍然已注册,但系统速度变慢,最终可能导致未分配的对象错误。

编辑#1:我确实可以访问正在导入的框架,但我没有看到导致问题的类中有任何奇怪的东西。

编辑#2:我刚刚收到一封发送给iOS 7.1的电子邮件。我很想知道这是否会消失,或者变得更糟,还是可以解决。

objective-c ios7 core-graphics
26个回答
162
投票

其他人会要求您发布访问核心图形上下文的代码,但我怀疑这是问题所在。这些无效的上下文0x0错误消息很常见,很容易在iOS 7中重现。事实上,我可以使用带有零代码的storyboard重现错误。我将UITextField拖到IB的画布上,运行应用程序,然后在文本字段内双击。

在许多情况下,我很难认真对待无效的上下文0x0错误消息。我不知道你的情况是否值得更加关注(我同意Rob Napier的说法值得调查,特别是如果你明确使用图形上下文的话)。

在我自己的项目中,我希望有一天这些错误中的许多都会神奇地消失(但那一天并没有带来7.0.3)。

更新:安装Xcode 5.1并定位iOS 7.1后,我无法再通过在空文本字段内双击来重现错误。


2
投票

我有从UIGraphicsGetCurrentContext()返回的上下文是NULL的情况,如果你尝试使用它的任何信息出现。在调用UIGraphicsPushContext之前使用drawRect:推送上下文是视图的责任,如果直接调用drawRect:而不是[view setNeedsDisplay],则可能导致上下文未被设置。我的预感是,在iOS 7之前,init上的视图被推送,现在在iOS 7上,直到第一次调用drawRect:时才会推送上下文。我怀疑一些UIKit代码直接调用drawRect:,这就是为什么即使没有自定义绘图也存在某些代码的问题。

解决方案(如果做自定义绘图):

  1. 不要直接调用drawRect:,使用[view setNeedsDisplay]或者如果你需要立即使用[view.layer draw]
  2. 在你的drawRect:获取上下文但不要在此if语句的正文之外使用它if (context) {<do drawing here>}

2
投票

在受影响的视图中关闭自动布局会导致此错误在您放置和移动视图中的UI元素(尤其是以编程方式绘制的自定义元素)的某些情况下消失。当我发现这个症状时,我正在使用JVFloatLabeledTextField。


2
投票

在某些情况下,您可能需要包含#import <QuartzCore/QuartzCore.h>行。


2
投票

我在自定义CALayer实现的drawInContext(..)方法中遇到此错误。 UIBezierPath尝试使用UIGraphicsGetCurrentContext(),默认情况下在自定义层中为零。 online documentation非常清楚地解释了这一点 -

但是,如果未使用UIView对象进行绘制,则必须使用UIGraphicsPushContext函数手动将有效上下文推送到堆栈。

这里的代码最终与我的内联注释一起使用(Swift代码,但解决方案是相同的)

override func drawInContext(ctx: CGContext!) {  
    var path = UIBezierPath()

    // 1. Make sure you push the CGContext that was first passed into you.
    UIGraphicsPushContext(ctx)
    path.moveToPoint(CGPoint(x: 0, y: 0))
    path.addLineToPoint(CGPoint(x: 150, y: 150))
    var lineColor = UIColor.blueColor()
    lineColor.setStroke()
    path.lineWidth = 2
    path.stroke(
    // 2. Pop the context after you are done.
    UIGraphicsPopContext()
}

2
投票

在我的情况下,我在创建带有cap insets的可调整大小的图像时遇到此警告。问题是我没有在“无上限”区域留下至少1个像素。

    UIImage *image = [UIImage imageNamed:@"name"];
    UIEdgeInsets edgeInsets = UIEdgeInsetsMake(20, 10, 20, 10);  //Problem here if the width is 20 or the height is 40
    image = [image resizableImageWithCapInsets:edgeInsets];

1
投票

我使用下面的代码从上下文创建UIImage:

    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, (CGRect){.size = size});

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

因此我得到了错误。

所以我删除了派生数据内容,重新启动了我的XCode。它奏效了。


1
投票

我也有同样的问题。在我的项目中,我尝试创建一个textField并将其添加到我的pdf文件中。旧代码:

- (void) drawInContext:(CGContextRef)context {
    //Otherwise we're upside-down
    CGContextSetTextMatrix(context, CGAffineTransformMake(1.0,0.0, 0.0, -1.0, 0.0, 0.0));

    CGContextSetTextDrawingMode(context, kCGTextFill); // This is the default
    [[UIColor blackColor] setFill]; // ***This is the problem ***

    CGFloat x = self.rect.origin.x;
    CGFloat y = self.rect.origin.y + self.font.pointSize;
    [self.text drawAtPoint:CGPointMake(x, y)
            withAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"Arial" size:12]}];
}

解决了这个问题后,代码改变了:

old:[[UIColor blackColor] setFill]; 

new:CGContextSetFillColorWithColor(context, [[UIColor blackColor] CGColor]);

我在UIColor SetFill doesn't work找到了解决方案。谢谢你的帮助。


1
投票

我收到了代码错误

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:pointA];
[path addLineToPoint:pointB];
[path addLineToPoint:pointC];
[[UIColor colorWithHexString:@"EFEFEF"] set];
[path fill];
[path closePath];

CAShapeLayer *triangle = [CAShapeLayer layer];
triangle.fillColor = [UIColor colorWithHexString:@"EFEFEF"].CGColor;
triangle.path = path.CGPath;

return triangle;

并删除代码后

[[UIColor colorWithHexString:@"EFEFEF"] set];
[path fill];

世界变得沉默


0
投票

对我来说,答案是我在drawRect:中不必要地发布了图形上下文。在CGPostError上抛出一个符号断点让我指出了罪魁祸首。


0
投票

我设置了这个错误

textfield.delegate = self

没有实现任何委托例程。删除该行解决了我的问题


200
投票

如果你很好奇是什么代码导致这些日志,你可以在add a symbolic breakpointCGPostError


0
投票

当我只用占位符文本触摸空白字段时,我在UITextField中遇到了这个问题。我使用以下解决方法来消除空白字段:

-(void)textFieldDidBeginEditing:(UITextField *)textField{

        textField.text=[@" " stringByAppendingString:textField.text];

        //other stuff here
}


-(BOOL)textFieldShouldReturn:(UITextField *)textField{

         if(textField.text.length>0){
             if([[textField.text substringToIndex:1] isEqualToString:@" "])
                 textField.text=[textField.text substringFromIndex:1];
         }
         //  other stuff here
}

0
投票

对我来说,我得到了这个错误,因为我发布了CGContextRef,如下所示:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    // DRAW BACKGROUND CIRCLE
    CGContextSetFillColorWithColor(context, [[UIColor gray] colorWithAlphaComponent:0.6].CGColor);
    CGContextFillEllipseInRect(context, rect);

//    CGContextRelease(context);
}

删除版本解决了这个问题


0
投票

当我在UIActivity子类的activityImage方法中输入错误的图像名称时,我得到了它

- (UIImage *)activityImage
{
    return [UIImage imageNamed:@"img.png"];
}

键入正确的图像为我解决了它。


0
投票

从模拟器卸载应用程序并再次运行


0
投票

像其他评论过的人一样,当我做以下任何事情时,我收到了这个警告:

在空白文本字段上:双击,触摸并按住,长单击。

这似乎只影响iOS 7.0.3

我发现了一个解决方法,如果您的粘贴板不是NULL,则不会触发警告。

所以我在textFieldDidBeginEditing中执行了以下操作:

- (void)textFieldDidBeginEditing:(UITextField *)textField {

    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    if (pasteboard.string.length == 0) {

        pasteboard.string = @" ";

    }
}

我在iphone 4s,5和5s的iOS 7.0.3模拟器中对此进行了测试,不再收到警告。我也在iphone 6和6 plus的iOS 8模拟器中对此进行了测试,但我不相信iOS 8会受到影响。

在发现这项工作之前经历了两天的挫折,所以我真的希望我的回答可以帮助那些遇到同样问题的人。


0
投票

如果在使用UIBezierPath并为笔划或填充设置颜色时发生错误,请将设置的颜色代码放在drawRect函数中而不是其他位置。


0
投票

这很hacky但它​​对我有用。

我在UIImageViewUITableViewCell设置了init,给它一个大小和限制。

然后在我的视图控制器的cellForRowAtIndexPath我这样做:

let img = PFImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
img.setImage(withFile: nil, defaultText: message.senderUsername)
cell.profileImageView?.image = img.image

这避免了错误,然后低于函数我设置UIImageView的实际图像。上面的代码是一个很好的默认值


42
投票

这些类型的错误在历史上是在不在drawRect内建立的上下文中或在UIGraphicsBeginImageContextUIGraphicsEndImageContext之类的调用之间调用Core Graphics函数的结果(或者像开始和结束上下文的其他UIKit函数)。

尽管如此,bilobatum是正确的,这个特定的错误序列可能是他在答案中引用的iOS 7错误的结果。如果没有在你的iOS6目标中看到这些错误,或者在快速扫描这个私有框架之后你没有发现任何可疑的Core Graphics调用,那么它可能就是这个iOS 7错误。好的捕获,bilobatum!


26
投票
UIGraphicsBeginImageContext( size );
CGContextRef context = UIGraphicsGetCurrentContext();

确保size.width或size.height不为0,

您可以将符号断点添加到CGPostError以进行检查


19
投票

我有一个简单的UITextField问题(键盘没有显示和控制台上的许多不同的无效上下文错误消息)。我只是通过查看SO上的另一个问题来找到解决方法:Cannot find executable for CFBundle CertUIFramework.axbundle

做就是了:

单击iOS模拟器>重置内容和设置...然后再次运行。

问题不应该再存在了


16
投票

在我的情况下,我在这段代码中遇到了这些错误:

CAShapeLayer *shapeLayer = [CAShapeLayer layer];
UIBezierPath *path;

path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 0)];
[path addLineToPoint:CGPointMake(size*2, 0)];
[path addLineToPoint:CGPointMake(size, size*2)];
[path closePath];
[path fill];

shapeLayer.path = path.CGPath;
shapeLayer.strokeColor = [[UIColor blackColor] CGColor];
shapeLayer.fillColor = color;
shapeLayer.lineWidth = width;

[self addSublayer:shapeLayer];

经过一些思考和测试后我发现了问题 - 就是这个电话:

[path fill];

当我检测到 - 在我的代码中,这个调用是没有必要的,因为填充将通过其他方式完成 - 所以我只是删除它。


5
投票

我有同样的问题,我忘了导入QuartzCore / QuartzCore.h,这解决了我的这些错误的问题。

    #import <QuartzCore/QuartzCore.h>

5
投票

直接答案:问题是因为除了- (void)drawRect:(CGRect)rect这个方法之外你已经使用了像CGContext等核心图形元素。

现在请将您的代码移动到此方法。它会strop给你警告/错误。


4
投票

我收到此错误是因为我使用UIColor对象作为CATextLayer对象中使用的NSAttributedString字典中的属性。我更改了字典以容纳CGColorRef,错误消失了。

[wordAttributes setObject:(id)[UIColor whiteColor].CGColor forKey:(NSString*)kCTForegroundColorAttributeName];
© www.soinside.com 2019 - 2024. All rights reserved.