CoreGraphics 随机崩溃
CoreGraphics random crash
这是一个小测试程序,用于在更大的 class 中复制间歇性问题。真正的class创建了4个大小不一的拇指
此 main.m 程序将在 运行 和 EXC_BAD_ACCESS 的 5 次中崩溃 1 次并突出显示 CGImageRelease(imgRef);如果我注释掉 CGImageRelease(imgRef) 那么应用程序会遇到严重的内存泄漏但不会崩溃...
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSString * image = @"/Users/xxx/Pictures/wallpaper/7gjMT.jpg";
NSData * imageData = [NSData dataWithContentsOfFile:image];
CFDataRef imgData = (__bridge CFDataRef)imageData;
CGImageRef imgRef;
CGDataProviderRef imgDataProvider = NULL;
imgDataProvider = CGDataProviderCreateWithCFData(imgData);
imgRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(imgDataProvider);
for (int i = 0; i < 1000; i++) {
// create context, keeping original image properties
CGColorSpaceRef colorspace = CGImageGetColorSpace(imgRef);
CGContextRef context = CGBitmapContextCreate(NULL, 2560, 1440,
CGImageGetBitsPerComponent(imgRef),
CGImageGetBytesPerRow(imgRef),
colorspace,
kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorspace);
// draw image to context (resizing it)
CGContextDrawImage(context, CGRectMake(0, 0, 2560, 1440), imgRef);
// extract resulting image from context
CGImageRef newImgRef;
newImgRef = CGBitmapContextCreateImage(context);
CGImageRelease(imgRef);
CGContextRelease(context);
imgRef = newImgRef;
}
}
return 0;
}
我发现如果我先释放上下文,那么 10 次失败中有 1 次会突出显示 CGImageGetBytesPerRow(imgRef) 并出现相同的错误。
我为 malloc_error_break 添加了一个断点并在 CGImageRelease 上得到了这个:
CGImageRelease 和 CGImageRelease 是否释放共享资源?
主要问题几乎可以肯定是您发布了一种您不拥有的颜色space。 CGImageGetColorSpace(imgRef)
不会为您提供返回的 colorspace 对象的所有权,因此您以后不应该调用 CGColorSpaceRelease(colorspace)
。 (顺便说一句,虽然我碰巧遇到了一个不同的故障,使我陷入了这个问题,但静态分析器也发现了这个问题。)
作为次要问题,我无法创建上下文,因为您使用的每行字节数不合适。 CGImageGetBytesPerRow(imgRef)
是该图像的每行字节数,但这仅适用于该图像的宽度。鉴于您是硬编码宽度而不是使用图像的宽度(因为您正在缩放),您不应该使用图像的每行字节数。
我想如果你按比例缩小它会起作用,但它会浪费 space。如果你正在扩大规模,它会失败。
在任何情况下,传递 0。这样 CGBitmapContextCreate()
可以计算出最佳值。
这是一个小测试程序,用于在更大的 class 中复制间歇性问题。真正的class创建了4个大小不一的拇指
此 main.m 程序将在 运行 和 EXC_BAD_ACCESS 的 5 次中崩溃 1 次并突出显示 CGImageRelease(imgRef);如果我注释掉 CGImageRelease(imgRef) 那么应用程序会遇到严重的内存泄漏但不会崩溃...
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSString * image = @"/Users/xxx/Pictures/wallpaper/7gjMT.jpg";
NSData * imageData = [NSData dataWithContentsOfFile:image];
CFDataRef imgData = (__bridge CFDataRef)imageData;
CGImageRef imgRef;
CGDataProviderRef imgDataProvider = NULL;
imgDataProvider = CGDataProviderCreateWithCFData(imgData);
imgRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(imgDataProvider);
for (int i = 0; i < 1000; i++) {
// create context, keeping original image properties
CGColorSpaceRef colorspace = CGImageGetColorSpace(imgRef);
CGContextRef context = CGBitmapContextCreate(NULL, 2560, 1440,
CGImageGetBitsPerComponent(imgRef),
CGImageGetBytesPerRow(imgRef),
colorspace,
kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorspace);
// draw image to context (resizing it)
CGContextDrawImage(context, CGRectMake(0, 0, 2560, 1440), imgRef);
// extract resulting image from context
CGImageRef newImgRef;
newImgRef = CGBitmapContextCreateImage(context);
CGImageRelease(imgRef);
CGContextRelease(context);
imgRef = newImgRef;
}
}
return 0;
}
我发现如果我先释放上下文,那么 10 次失败中有 1 次会突出显示 CGImageGetBytesPerRow(imgRef) 并出现相同的错误。
我为 malloc_error_break 添加了一个断点并在 CGImageRelease 上得到了这个:
CGImageRelease 和 CGImageRelease 是否释放共享资源?
主要问题几乎可以肯定是您发布了一种您不拥有的颜色space。 CGImageGetColorSpace(imgRef)
不会为您提供返回的 colorspace 对象的所有权,因此您以后不应该调用 CGColorSpaceRelease(colorspace)
。 (顺便说一句,虽然我碰巧遇到了一个不同的故障,使我陷入了这个问题,但静态分析器也发现了这个问题。)
作为次要问题,我无法创建上下文,因为您使用的每行字节数不合适。 CGImageGetBytesPerRow(imgRef)
是该图像的每行字节数,但这仅适用于该图像的宽度。鉴于您是硬编码宽度而不是使用图像的宽度(因为您正在缩放),您不应该使用图像的每行字节数。
我想如果你按比例缩小它会起作用,但它会浪费 space。如果你正在扩大规模,它会失败。
在任何情况下,传递 0。这样 CGBitmapContextCreate()
可以计算出最佳值。