【问题标题】:Freeing programmatically modified UIImage throws exception释放以编程方式修改的 UIImage 会引发异常
【发布时间】:2013-11-12 20:31:19
【问题描述】:

我编写了一个图像过滤器,它从旧的一个像素一个像素地生成一个新的 UIImage。在包含我的图像的类中,声明如下:

@property   UIImage *imageHandle;       // contains the image of the class

我的 CBImage 类中的过滤器从 UIImage 中将位图提取为 char 数组(像素),分配一个具有相同大小的新 char 数组缓冲区(newPixels),然后遍历 RGBA 像素以在 newPixels 中重建过滤后的图像.最后它会生成一个新的 UIImage 并返回它。

这是代码(CBImage 是我的类,其中包含上述声明):

-(CBImage *)doMyFancyStuff
{
// set up some convenience variables
UIImage *image = self.imageHandle;
CGImageRef imageRef = image.CGImage;
NSData *imageData = (NSData *)CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));
NSLog(@"NumPixels %d", [imageData length]);
char *pixels = (char *)[imageData bytes];

char *newPixels = (char *)calloc([imageData length], sizeof(char));

// run through the image and manipulate the image
for (NSInteger i=0; i< [imageData length]; i+=4)
{
    if ([whatEverIWantIsTrueForMyFilter])
    {
        // color pixel white and ALPHA = 1.0
        newPixels[i] = 255;
        newPixels[i+1] = 255;
        newPixels[i+2] = 255;
        newPixels[i+3] = 255;
    }
    else
        newPixels[i+3] = 0;  // make pixel translucent
}

// create new image
CBImage *result = [[CBImage alloc] init];

// construct new UImage 
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef);
size_t bytesPerRow = CGImageGetBytesPerRow(imageRef);

CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, newPixels, [imageData length], NULL);

CGImageRef newImageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorspace, bitmapInfo, provider, NULL, FALSE, kCGRenderingIntentDefault);

result.imageHandle = [UIImage imageWithCGImage:newImageRef];

// clean up
free(pixels);
free(newPixels);
CGImageRelease(imageRef);
CGColorSpaceRelease(colorspace);
CGDataProviderRelease(provider);
CGImageRelease(newImageRef);
newImageRef = Nil;

return result;

}

这一切似乎都很好,我可以在我的视图控制器中显示新创建的 UImage:

CBImage *overlayImage = [testCBImage doMyFancyStuff];
self.overlayView.image = overlayImage.imageHandle;

但是......如果我想再次释放图像,则会引发 BAD_ACCESS 异常:

self.overlayView.image = Nil;

我不知道这里出了什么问题。我唯一的怀疑是上面过滤器方法中第 10 行中的 calloc 调用,因为我有点“手动”分配内存(尽管我在方法结束时再次释放它),然后当UIImage 句柄设置为 Nil...但我不确定。

我正在使用 iOS7 和 ARC。

有什么想法吗?

贝斯基

【问题讨论】:

  • 将这个:@property UIImage *imageHandle; 改为:@property (nonatomic, strong) UIImage *imageHandle;

标签: ios objective-c exception automatic-ref-counting calloc


【解决方案1】:
char *pixels = (char *)[imageData bytes];

然后,稍后...

free(pixels);

但是,像素不是使用create / malloc / ...等创建的,不需要释放。

另外,请考虑使用 retain(或强,相同的东西)声明属性。

@property (nonatomic, retain)UIImage *imageHandle;       // contains the image of the class

【讨论】:

  • 谢谢...意识到这一点。但即使对此发表评论也无济于事。异常不是在过滤器方法中抛出,而是在释放使用“newPixels”位图的 UIImage 时在视图控制器中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多