Что может вызвать сбой [UIImage imageWithData] при его возврате - PullRequest
2 голосов
/ 07 января 2012

У меня есть этот код в одном из моих NSManagedObjects:

if (self.tempImageStorage) {
    return self.tempImageStorage;
} else if(self.imageData) {
    NSLog(@"%@ %d",self.imageData, self.imageData.length);
    self.tempImageStorage = [UIImage imageWithData:self.imageData];
    return self.tempImageStorage;
}

Иногда, обычно, когда я быстро пролистываю изображения, он возвращается с EXC_BAD_ACCESS на 5-й строке(UIImage imageWithData line), и я не могу po (printobject) self в консоли, поэтому я предполагаю, что сам NSMananagedObject был освобожден.Что не имеет смысла, так это то, что он мог ссылаться на себя для 2 ifs, и я даже записываю данные изображения и его длину прямо перед ним.

Как можно было освободить NSManagedObject в течение этого периода, так как все это происходит в одном и том же потоке (и это основной поток)?

PS: У меня включены зомби, но он все ещене позволяет мне самому.

Код, который устанавливает данные изображения:

- (void) processRequest:(ASIHTTPRequest *) request
{
    UIImage * orig = [UIImage imageWithData:[request responseData]];
    CGSize targetSize = isPad()?CGSizeMake(446,150):CGSizeMake(320, 108);
    CGRect fourPanelSize = CGRectMake(0, 0, 1000, 336);
    CGImageRef imageRef = CGImageCreateWithImageInRect([orig CGImage], fourPanelSize);
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);

    if (bitmapInfo == kCGImageAlphaNone || bitmapInfo == kCGImageAlphaLast) {
        bitmapInfo = kCGImageAlphaPremultipliedLast;
    }

    CGContextRef bitmap;
    bitmap = CGBitmapContextCreate(NULL, targetSize.width, targetSize.height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);    

    CGContextDrawImage(bitmap, CGRectMake(1, 1, targetSize.width-2, targetSize.height-2), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage* newImage = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);
    CGImageRelease(ref);

    NSData * thumbData = UIImagePNGRepresentation(newImage);
    NSData * imageData = UIImagePNGRepresentation(orig);

    //Post notification on main thread since it will be updating the UI
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        self.tempImageThumbStorage = newImage;
        self.imageThumbnailData = thumbData;
        self.tempImageStorage = orig;
        self.imageData = imageData;

        [(AppDelegate*)[UIApplication sharedApplication].delegate saveContext];

        NSMutableDictionary * userInfo = [[NSMutableDictionary alloc] initWithCapacity:1];
        [userInfo setObject:[NSNumber numberWithBool:YES] forKey:@"status"];
        [userInfo setObject:self forKey:@"comic"];

        [[NSNotificationCenter defaultCenter] postNotificationName:PCRLoadMediahNotification object:self userInfo:userInfo];
        strongSelf = nil;
    }];

}

Ответы [ 2 ]

2 голосов
/ 09 января 2012

Оказывается, я слишком часто сохранял контекст, из-за чего imageData не сохранялся на диск должным образом и вызывал исключение.

0 голосов
/ 30 мая 2017

Я столкнулся с той же проблемой, когда анализировал изображение из Интернета. Итак, когда я воссоздал изображение в приложении, у меня произошел сбой примерно так:

UIImage *img = [UIImage imageWithData:imgData] -> EXC_BAD_ACCESS (code =2 0x...)

Поэтому моя проблема заключалась в том, что я не синхронизировал это действие с основным потоком приложения, поэтому мое приложение зависало. Самое странное: симуляторы прекрасно работают, когда происходит сбой реального устройства.

Для синхронизации я добавил это действие:

  • (void) GetImage: (NSData *) номер imgData: (int) i {

    [[NSOperationQueue mainQueue] addOperationWithBlock: ^ { @synchronized (imgData) { // UIImage * img2 = [UIImage imageWithData: imgData]; NSLog (@ "номер изображения% d", i); uiimager_array [i] = [UIImage imageWithData: imgData]; } }];

}

После этого я вызываю в своем цикле эту пустую функцию, которая теперь не приводит к сбою приложения. Хмель, который помогает

...