1

在针对 iPhone OS 3.0 SDK 进行开发时,我发现了一个错误。基本上,如果我从位图图像上下文创建 CGImage,我在释放它时会收到以下错误:

malloc: *** error for object 0x1045000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

以下是相关代码:

CGSize size = CGSizeMake(100, 100);
CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
size_t bitsPerComponent = 8;
size_t bytesPerPixel = 4;
size_t bytesPerRow = size.width * bytesPerPixel;
void *bitmapData = calloc(size.height, bytesPerRow);
CGContextRef ctxt = CGBitmapContextCreate(bitmapData, size.width, size.height, bitsPerComponent, bytesPerRow, cs, kCGImageAlphaPremultipliedLast);
// we could draw something here, but why complicate things?
CGImageRef image = CGBitmapContextCreateImage(ctxt);
CGContextRelease(ctxt);
free(bitmapData);
CGColorSpaceRelease(cs);
CGImageRelease(image); // This triggers the error message.

上面的例子是独立的,很明显没有违反保留/释放规则。我已经在 3.0、3.1 和 3.1.2 下的 iPhone 模拟器上测试了这段代码。该问题仅在3.0下出现;它似乎已在 3.1 及更高版本中修复。我还没有确认设备上的错误。

4

1 回答 1

1

问题指针似乎是图像的数据提供者。如果我在释放图像之前插入此行:

CFRetain(CGImageGetDataProvider(image));

那么在 3.0 上一切都很好。但是,如果应用程序在更高版本的操作系统上运行,则数据提供程序将被泄露。因此,您必须检查操作系统版本或直接忽略它(malloc 会记录错误消息,但不会引发异常或以任何方式中断应用程序)。我一直在使用以下宏:

#if TARGET_IPHONE_SIMULATOR
// 3.0 CFVersion 478.470000
// 3.1 CFVersion 478.520000
#define BugFixRetainImageDataProvider(img) \
    if (kCFCoreFoundationVersionNumber == 478.47) { \
        CGDataProviderRef dp = CGImageGetDataProvider(img); \
        if (dp) CFRetain(dp); \
    }
#else
#define BugFixRetainImageDataProvider(img)
#endif

由于我无法在设备上重现它(我没有任何运行 3.0 的设备),因此我仅在模拟器上应用此修复程序。

于 2009-12-28T07:58:04.747 回答