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]
欢迎补充