2016-07-26 3 views
0

У меня есть код, который создавая UIImage динамически из байтового буфера и назначая вновь созданный UIImage для UIImageView.image собственности:Получение EXC_BAD_ACCESS при попытке использовать dynamicaly созданный UIImage в UIImageView

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 6с, но он выходит из строя на моем 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 пуст, т.е. Пуск-> Main-> UIApplicationMain

Я использую iOS 9.3.3 для iPhone 6 и iPad2. Целевая платформа - 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 (...)

Любая идея?

Спасибо!

ответ

0

Итак, прежде всего, после того, как вы создали CGColorSpaceRef и CGImageRef сохранить счетчик увеличился и 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; 
} 

Надеется, что это поможет исправить аварии

+0

Нет, это не исправляет мою проблему. Как я уже сказал, это хорошо работает со вторым методом, но он не работает с первым, и он работает только на iPad 2. И не похоже, что проблема связана с утечкой ресурсов, потому что он сбой в начале. Но спасибо за советы. – Tutankhamen

+0

@Tutankhamen: вы пробовали 'CFRelease (imageRef);'? – Lion

+0

есть, я сделал. Я добавил CFRelease (imageRef) и CGColorSpaceRelease (colorSpaceRef), но я все еще получаю то же исключение ... – Tutankhamen

Смежные вопросы