我有一个绘制图像的类。对于多个图像源,它被多次实例化,并且可以同时具有多个这些对象;每个都获得一个中断驱动的馈送(来自USB设备)。
该类的部分功能是注释所输入的图像,因此有一个例程可以执行一些标准的Core Graphics内容来添加注释。
我通过位图上下文执行此操作,首先使用标准CGContext内容绘制图像,然后添加注释。
问题在于,当我这样做时,来自多个来源的图像彼此重叠。它看起来像一个既定的背景;即使是位图上下文,也不是线程安全的。但是,我添加了NSLock,并没有解决问题,因此它可能不仅仅是线程安全问题。
这是例程的简化版本:
- (CGImageRef)createCopiedImage:(CGImageRef)inImage
{
CGImageRef ret = nil;
CGRect imageRect = CGRectMake ( 0, 0, CGImageGetWidth ( ret ), CGImageGetHeight ( ret ) );
size_t rowBytes = imageRect.size.width * 4;
size_t bufferLen = rowBytes * imageRect.size.height;
void *buffer = malloc ( bufferLen );
if ( buffer )
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName ( kCGColorSpaceGenericRGB );
if ( colorSpace )
{
CGContextRef drawingContext = CGBitmapContextCreate ( buffer, imageRect.size.width, imageRect.size.height, 8, rowBytes, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst );
if ( drawingContext )
{
CGContextDrawImage ( drawingContext, imageRect, inImage );
CFRelease ( backGroundImage );
// DO ANNOTATION STUFF HERE
CGDataProviderRef dataProvider = CGDataProviderCreateWithData ( NULL, buffer, rowBytes * imageRect.size.height, NULL );
if ( dataProvider )
{
CGImageRef ret = CGImageCreate ( imageRect.size.width, imageRect.size.height, 8, 32, rowBytes, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst, dataProvider, NULL, false, kCGRenderingIntentDefault );
CGDataProviderRelease ( dataProvider) ;
}
CGContextRelease ( drawingContext );
}
free ( buffer );
}
return ret;
}
关于如何避免这些情况相互踩踏的任何想法?
答案 0 :(得分:1)
不能承受内存泄漏,您应该能够让系统为您处理内存分配,并使用新创建的图形来复制出CGImageRef:
@implementation YourClass
- (CGImageRef)createCopiedImage:(CGImageRef)inImage
{
CGImageRef ret = NULL;
CGRect imageRect = CGRectMake ( 0, 0, CGImageGetWidth ( ret ), CGImageGetHeight ( ret ) );
size_t rowBytes = imageRect.size.width * 4;
size_t bufferLen = rowBytes * imageRect.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName ( kCGColorSpaceGenericRGB );
if ( colorSpace )
{
CGContextRef drawingContext = CGBitmapContextCreate ( NULL, imageRect.size.width, imageRect.size.height, 8, rowBytes, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst );
if ( drawingContext )
{
CGContextDrawImage ( drawingContext, imageRect, inImage );
CFRelease ( backGroundImage );
// DO ANNOTATION STUFF HERE
// Copy image out
ret = CGBitmapContextCreateImage(drawingContext);
CGContextRelease ( drawingContext );
}
}
return ret;
}
@end