在UIImageView

时间:2016-07-26 05:09:17

标签: ios objective-c iphone uiimageview uiimage

我有一个代码,可以从字节缓冲区动态创建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-&gt; main-&gt; 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(...)

有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

首先,在您创建CGColorSpaceRefCGImageRef保留计数增加并且ARC不会自行释放并且可能导致泄漏之后,您需要调用CGColorSpaceRelease(colorSpaceRef)并且CFRelease(imageRef);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;
}

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

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