【问题标题】:Getting EXC_BAD_ACCESS when trying to use dynamicaly created UIImage in UIImageView尝试在 UIImageView 中使用动态创建的 UIImage 时获取 EXC_BAD_ACCESS
【发布时间】:2023-03-12 17:12:01
【问题描述】:

我有一个从字节缓冲区动态创建 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

所以,在模拟器和我的 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为空,即start->main->UIApplicationMain

我在 iPhone 6s 和 iPad2 上都使用 iOS 9.3.3。目标平台是 iOS 9.0

顺便说一句。 UIImage 创建后看起来没问题。如果我用这样的东西替换我的 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;
}

然后一切正常。所以,我怀疑我用 CGImageCreate(...)CGDataProviderCreateWithData(...)

做错了什么

有什么想法吗?

谢谢!

【问题讨论】:

    标签: ios objective-c iphone uiimageview uiimage


    【解决方案1】:

    首先,在您创建了CGColorSpaceRefCGImageRef 保留计数增加并且ARC 不会自行释放并且可能导致泄漏之后,您需要调用CGColorSpaceRelease(colorSpaceRef)CFRelease(imageRef); 和@987654325 @

    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;
    }
    

    在您的第二种方法中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;
    }
    

    希望这有助于解决您的崩溃问题

    【讨论】:

    • 不,它不能解决我的问题。正如我所说,它适用于第二种方法,但它不适用于第一种方法,并且仅适用于 iPad 2。而且看起来问题不在于资源泄漏,因为它在一开始就崩溃了。但是感谢您的提示。
    • @Tutankhamen : 你试过CFRelease(imageRef); 吗?
    • 是的,我做到了。我添加了 CFRelease(imageRef) 和 CGColorSpaceRelease(colorSpaceRef),但我仍然遇到同样的异常......
    • @Tutankhamen 我更新了答案并添加了CGDataProviderRelease(provider); 尝试并尝试连接您的设备并检查思想仪器以检测任何内存泄漏
    • @Tutankhamen 你有想过这个吗?有同样的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多