Что вызывает это EXC_CRASH в моем приложении для iPad? - PullRequest
1 голос
/ 17 февраля 2011

Я получил эту символическую трассировку стека из отчета о сбое в моем приложении для iPad (отрывок):

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread:  0

0   ImageIO         0x34528eb4 _CGImagePluginIdentifyPNG + 0
1   ImageIO         0x34528d90 _CGImageSourceBindToPlugin + 368
2   ImageIO         0x34528bda CGImageSourceGetCount + 26
3   UIKit           0x341b8f66 _UIImageRefAtPath + 366
4   UIKit           0x342650ce -[UIImage initWithContentsOfFile:] + 50
5   UIKit           0x342b0314 +[UIImage imageWithContentsOfFile:] + 28
6   DesignScene     0x00013a2a -[LTImageCache fetchImageforURL:] (LTImageCache.m:37)
…

Вот содержимое -[LTImageCache fetchImageforURL:]:

- (UIImage *)fetchImageforURL:(NSString *)theUrl {
    NSString *key = theUrl.md5Hash;
    return [UIImage imageWithContentsOfFile:[self filenameForKey:key]];
}

Исодержимое -[LTImageCache filenameForKey:]:

- (NSString *) filenameForKey:(NSString *) key {
    return [_cacheDir stringByAppendingPathComponent:key];
}

Ивар _cacheDir создается и сохраняется в -init.Итак, вопрос в том, что вызвало этот сбой?Проблема в том, что:

  1. необходимо сохранить возвращаемое значение -[LTImageCache filenameForKey:] (оно автоматически высвобождается)
  2. Где-то необработанное исключение (+[UIImage imageWithContentsOfFile:] утверждает, что возвращает nil, еслиизображение неузнаваемо)
  3. Что-то еще ... Я не догадываюсь

Я думаю, что значение с автоматически выпущенным значением будет в порядке.По правде говоря, этот код работал отлично в течение нескольких месяцев, и этот метод вызывается сотни раз за сеанс.Это редкий сбой при очень специфических обстоятельствах (приложение остается загруженным на ночь, сбой при утренней разблокировке iPad).

Что вызывает этот сбой?

1 Ответ

1 голос
/ 22 февраля 2011

Я предполагаю, но это похоже на поддельный файл изображения.Это в вашем приложении или вы загружаете его?

Я не думаю, что это имеет какое-либо отношение к памяти mgt.

Чтобы проверить, вы можете попробовать использовать ImageIO, чтобы открыть файл самостоятельно.

  CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)self.url, NULL);
  if(NULL != imageSource) {
    size_t imageCount = CGImageSourceGetCount(imageSource);
    if(imageCount > 0) {
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                   [NSNumber numberWithBool:YES], kCGImageSourceCreateThumbnailFromImageIfAbsent,
                                   [NSNumber numberWithInteger:maxSize], kCGImageSourceThumbnailMaxPixelSize, nil];
        CGImageRef thumbImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (CFDictionaryRef)options);
        self.image = [UIImage imageWithCGImage:thumbImage scale:scale orientation:imageOrientation];
        CGImageRelease(thumbImage);
        CFRelease(imageSource);
        [pool drain];
    }
  } else {
    NSLog(@"Unable to open image %@", self.url);
  }

и затем попытайтесь найти количество изображений.

Использование maxSize и получение миниатюры гарантируют, что вы не загрузите 5-мегапиксельное изображение для помещения вПлитка размером 100x100 в вашем пользовательском интерфейсе.

scale - это масштаб окна (для iPhone 4 будет 2 и 1 для всего остального).

Чтобы найти ориентацию, необходимо использовать CGImageSourceCopyPropertiesAtIndex функцию, а затем клавишу kCGImagePropertyOrientation, чтобы получить ориентацию конкретного изображения.

...