iOS17 CGContext造成的闪退统计

iOS17 CGContext造成的闪退,主要是绘图时,没有宽高调用CGContext引起的
一、YYKit
YYAsyncLayer.m文件

闪退信息

CrashDoctor Diagnosis: Application threw exception NSInternalInconsistencyException: UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={288, 0}, scale=3.000000, bitmapInfo=0x2002. Use UIGraphicsImageRenderer to avoid this assert.
Originated at or in a subcall of 
Thread 0 Crashed:
0   CoreFoundation                      0x000000018a26c870 0x18a180000 + 968816
1   libobjc.A.dylib                     0x0000000182587c00 0x18255c000 + 179200
2   Foundation                          0x00000001897d6e54 0x189120000 + 7040596
3   UIKitCore                           0x000000018c498380 0x18c3a4000 + 1000320
4   YYKit                               0x000000010fc8dadc 0x10fc38000 + 350940
5   YYKit                               0x000000010fc8d474 0x10fc38000 + 349300
        [_sentinel increase];
        if (task.willDisplay) task.willDisplay(self);
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, self.contentsScale);
        CGContextRef context = UIGraphicsGetCurrentContext();
        if (self.opaque) {
            CGSize size = self.bounds.size;
            size.width *= self.contentsScale;
            size.height *= self.contentsScale;
            CGContextSaveGState(context); {
                if (!self.backgroundColor || CGColorGetAlpha(self.backgroundColor) < 1) {
                    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
                    CGContextAddRect(context, CGRectMake(0, 0, size.width, size.height));
                    CGContextFillPath(context);
                }
                if (self.backgroundColor) {
                    CGContextSetFillColorWithColor(context, self.backgroundColor);
                    CGContextAddRect(context, CGRectMake(0, 0, size.width, size.height));
                    CGContextFillPath(context);
                }
            } CGContextRestoreGState(context);
        }
        task.display(context, self.bounds.size, ^{return NO;});
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        self.contents = (__bridge id)(image.CGImage);

        if (task.didDisplay) task.didDisplay(self, YES);

改成对宽高进行判断

        [_sentinel increase];
        if (task.willDisplay) task.willDisplay(self);
        if (self.bounds.size.width < 1 || self.bounds.size.height < 1) {
            CGImageRef image = (__bridge_retained CGImageRef)(self.contents);
            self.contents = nil;
            if (image) {
                CFRelease(image);
            }
            return;
        }
        UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:self.bounds.size];
        UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) {
            if (self.opaque) {
                if (!self.backgroundColor || CGColorGetAlpha(self.backgroundColor) < 1) {
                    CGContextSetFillColorWithColor(context.CGContext, [UIColor whiteColor].CGColor);
                    [context fillRect:self.bounds];
                }
                if (self.backgroundColor) {
                    CGContextSetFillColorWithColor(context.CGContext, self.backgroundColor);
                    [context fillRect:self.bounds];
                }
            }
            task.display(context.CGContext, self.bounds.size, ^{return NO;});
        }];
        self.contents = (__bridge id)(image.CGImage);

        if (task.didDisplay) task.didDisplay(self, YES);

二、YBImageBrowser
YBIBUtilities.m文件
闪退信息

CrashDoctor Diagnosis: Application threw exception NSInternalInconsistencyException: UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={0, 0}, scale=2.000000, bitmapInfo=0x2006. Use UIGraphicsImageRenderer to avoid this assert.
Originated at or in a subcall of base::internal::BindState<base::internal::RunnableAdapter<void (Closure::Callable<void (int, unsigned int, amap::vmap::ResourceWrapper*, bool*)>::*)(int const&, unsigned int const&, amap::vmap::ResourceWrapper* const&, bool* const&) const>, void (Closure::Callable<void (int, unsigned int, amap::vmap::ResourceWrapper*, bool*)> const*, int const&, unsigned int const&, amap::vmap::ResourceWrapper* const&, bool* const&), void (Closure::Callable<void (int, unsigned int, amap::vmap::ResourceWrapper*, bool*)>*, int, unsigned int, amap::vmap::ResourceWrapper*, bool*)>::destroy(base::internal::BindStateBase const*)
Thread 0 Crashed:
0   CoreFoundation                      0x0000000194204860 0x194118000 + 968800
1   libobjc.A.dylib                     0x000000018c50fc80 0x18c4e4000 + 179328
2   Foundation                          0x0000000193764f14 0x1930b4000 + 7016212
3   UIKitCore                           0x000000019643bbd4 0x196347000 + 1002452
4   GalaxyX                             0x00000001045506c8 YBIBSnapshotView + [YBIBUtilities.m : 94] 
5   GalaxyX                             0x0000000104552914 -[YBImageBrowser showToView:containerSize:] + [YBImageBrowser.m : 186] 
6   GalaxyX                             0x000000010455271c -[YBImageBrowser showToView:] + [YBImageBrowser.m : 159] 
7   GalaxyX                             0x00000001045526cc -[YBImageBrowser show] + [YBImageBrowser.m : 156] 
UIImage *YBIBSnapshotView(UIView *view) {
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, [UIScreen mainScreen].scale);
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

改成对传入的view以及其宽高进行判断

UIImage *YBIBSnapshotView(UIView *view) {
    if(![view isKindOfClass:UIView.class] || view.bounds.size.width<=1||view.bounds.size.height<=1){
        return UIImage.new;
    }
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, [UIScreen mainScreen].scale);
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

三、BVLinearGradient
BVLinearGradientLayer.m文件

闪退信息

CrashDoctor Diagnosis: Application threw exception NSInternalInconsistencyException: UIGraphicsBeginImageContext() failed to allocate CGBitampContext: size={0, 20}, scale=3.000000, bitmapInfo=0x2006. Use UIGraphicsImageRenderer to avoid this assert.
Originated at or in a subcall of __cxa_throw
Thread 0 Crashed:
0   CoreFoundation                      0x000000018cdbe5e0 __exceptionPreprocess + [ : 164] 
1   libobjc.A.dylib                     0x00000001850d7c00 objc_exception_throw + [ : 60] 
2   Foundation                          0x000000018c3284d4 -[NSMutableDictionary(NSMutableDictionary) initWithContentsOfFile:]
3   UIKitCore                           0x000000018efd88b0 0x18eee4000 + 1001648
4   BVLinearGradient                    0x0000000108fa47b4 -[BVLinearGradientLayer display] + [BVLinearGradientLayer.m : 58] 
5   QuartzCore                          0x000000018e32f51c CA::Layer::layout_and_display_if_needed(CA::Transaction*) + [ : 412] 
6   QuartzCore                          0x000000018e33594c CA::Context::commit_transaction(CA::Transaction*, double, double*) + [ : 464] 
7   QuartzCore                          0x000000018e32ec3c CA::Transaction::commit() + [ : 648] 
8   QuartzCore                          0x000000018e32e8e4 CA::Transaction::flush_as_runloop_observer(bool) + [ : 88] 
- (void)display {
    [super display];
    BOOL hasAlpha = NO;

    for (NSInteger i = 0; i < self.colors.count; i++) {
        hasAlpha = hasAlpha || CGColorGetAlpha(self.colors[i].CGColor) < 1.0;
    }

    UIGraphicsBeginImageContextWithOptions(self.bounds.size, !hasAlpha, 0.0);
    CGContextRef ref = UIGraphicsGetCurrentContext();
    [self drawInContext:ref];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    self.contents = (__bridge id _Nullable)(image.CGImage);
    self.contentsScale = image.scale;

    UIGraphicsEndImageContext();
}

改成对其宽高进行判断

- (void)display {
    [super display];

    if(!self || self.frame.size.width<1 || self.frame.size.height<1){
        
        return;
    }
    
    BOOL hasAlpha = NO;

    for (NSInteger i = 0; i < self.colors.count; i++) {
        hasAlpha = hasAlpha || CGColorGetAlpha(self.colors[i].CGColor) < 1.0;
    }

    UIGraphicsBeginImageContextWithOptions(self.bounds.size, !hasAlpha, 0.0);
    CGContextRef ref = UIGraphicsGetCurrentContext();
    [self drawInContext:ref];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    self.contents = (__bridge id _Nullable)(image.CGImage);
    self.contentsScale = image.scale;

    UIGraphicsEndImageContext();
}

四、高德地图
高德导航栏

2 GalaxyX 0x0000000102d8db1c +[AMapNaviImageUtility addBgimageAndArrowimageToImage:arrowImage:] + [ : 512]
Thread 37 name:  NaviService
Thread 37 Crashed:
0   CoreFoundation                      0x000000019b6a6294 0x19b4f0000 + 1794708
1   CoreFoundation                      0x000000019b4fcd0c 0x19b4f0000 + 52492
2   GalaxyX                             0x0000000100c172dc +[AMapNaviImageUtility addBgimageAndArrowimageToImage:arrowImage:] + [ : 512] 
3   GalaxyX                             0x0000000100bfe9bc -[AMapNaviCoreCombine onShowCrossImage:] + [ : 448] 
企业微信截图_69989b65-fe80-4ed6-bca3-6a27a82ca62e.png

欢迎补充

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,795评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,174评论 1 32
  • 一、iOS渲染架构 下图分别是iOS渲染早期架构和最新架构,可以看到在最新的架构中使用了Metal代替OpenGL...
    Jason1226阅读 1,385评论 0 3
  • 基于定时器的动画 NSTimer 其实动画原理就是每秒钟更新60次,timer也是同样的道理,我们用一个周期是1/...
    木小易Ying阅读 787评论 0 2
  • 基础 核心动画是 iOS 和 MacOS 上的图形渲染和动画基础结构,用于为应用的视图和其他视觉元素设置动画。 核...
    davon阅读 2,041评论 0 8