简体   繁体   English

尝试在UIImageView中使用动态创建的UIImage时获取EXC_BAD_ACCESS

[英]Getting EXC_BAD_ACCESS when trying to use dynamicaly created UIImage in UIImageView

I have a code which creating UIImage dynamically from byte buffer and assigning newly created UIImage to UIImageView.image property: 我有一个从字节缓冲区动态创建UIImage并将新创建的UIImage分配给UIImageView.image属性的代码:

UIImage* UIImageFromDibRect(long w, long h) {
    size_t dataSiz = w * h * 4;
    std::unique_ptr<uint8> data(new uint8[dataSiz]);
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data.get(), dataSiz, NULL);


    // set up for CGImage creation
    size_t bitsPerComponent = 8;
    size_t bitsPerPixel = 32;
    size_t bytesPerRow = 4 * w;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    CGImageRef imageRef = CGImageCreate(w, h, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    // make UIImage from CGImage
    UIImage *uiImage = [UIImage imageWithCGImage:imageRef];
    return uiImage;
}

[...]

@interface ScreenViewController ()
@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@end

[...]

@implementation ScreenViewController

-(void)myMethod {
    UIImage* newImage = UIImageFromDibRect(128, 128);
    self.imageView.image = newImage;
}

@end

So, everything works just perfect in emulator and on my iPhone 6s, but it crashes on my iPad 2 here: 因此,一切在模拟器和iPhone 6s上都可以完美运行,但在iPad 2上崩溃了:

  0x26bd3182 <+138>: ldr    r0, [r2]
  0x26bd3184 <+140>: blx    0x27507218                ; symbol stub for: -[_UIRemoteViewController(_UIRemoteViewController_AutomaticInvaldiation) autorelease]
> 0x26bd3188 <+144>: mov    r0, r5
  0x26bd318a <+146>: blx    0x27507268                ; symbol stub for: __strlcpy_chk$shim
  0x26bd318e <+150>: mov    r0, r4

callstack is empty, ie start->main->UIApplicationMain 调用堆栈为空,即开始->主-> UIApplicationMain

I use iOS 9.3.3 for both iPhone 6s and iPad2. 我将iOS 9.3.3用于iPhone 6s和iPad2。 Target platform is iOS 9.0 目标平台是iOS 9.0

btw. 顺便说一句 UIImage looks ok after creation. 创建后,UIImage看起来不错。 And if i replace my UIImageFromDibRect with something like this: 如果我用以下内容替换UIImageFromDibRect

UIImage* UIImageFromDibRect(long w, long h) {
    CGRect r = CGRectMake(0.0f, 0.0f, w, h);
    UIGraphicsBeginImageContext(r.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
    CGContextFillRect(context, r);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

Then everything is working just fine. 然后一切正常。 So, I'm suspicious I'm doing something wrong with CGImageCreate(...) or with CGDataProviderCreateWithData(...) 所以,我怀疑CGImageCreate(...)CGDataProviderCreateWithData(...)做错了什么

Any idea? 任何想法?

Thank you! 谢谢!

So first of all, after you created a CGColorSpaceRef and CGImageRef retain count increased and ARC will not release by yourself and it may cause a leak, you need a call CGColorSpaceRelease(colorSpaceRef) and CFRelease(imageRef); 因此,首先,在创建CGColorSpaceRefCGImageRef保留计数后,ARC不会自行释放,并且可能导致泄漏,您需要调用CGColorSpaceRelease(colorSpaceRef)CFRelease(imageRef); and CGDataProviderRelease(provider); CGDataProviderRelease(provider);

UIImage* UIImageFromDibRect(long w, long h) {
    size_t dataSiz = w * h * 4;
    std::unique_ptr<uint8> data(new uint8[dataSiz]);
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data.get(), dataSiz, NULL);


    // set up for CGImage creation
    size_t bitsPerComponent = 8;
    size_t bitsPerPixel = 32;
    size_t bytesPerRow = 4 * w;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    CGImageRef imageRef = CGImageCreate(w, h, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

    // make UIImage from CGImage
    UIImage *uiImage = [UIImage imageWithCGImage:imageRef];

    CFRelease(imageRef);
    CGColorSpaceRelease(colorSpaceRef);
    CGDataProviderRelease(provider);
    return uiImage;
}

and in your second method CGContextRef need release the same CGContextRelease(context); 在第二种方法中, CGContextRef需要释放相同的CGContextRelease(context);

UIImage* UIImageFromDibRect(long w, long h) {
    CGRect r = CGRectMake(0.0f, 0.0f, w, h);
    UIGraphicsBeginImageContext(r.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
    CGContextFillRect(context, r);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGContextRelease(context);

    return image;
}

Hope this help fix your crash 希望这能帮助您解决崩溃问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM