Png_error внутри UIImagePNGRпредставление только на iOS 5.1+

Мы столкнулись с необычным сбоем, когда UIImagePNGRпредставляет() иногда вызывает вызовы png_error. Мы не смогли воспроизвести эту ошибку на любом из наших устройств в доме.

Вот пример трассировки стека из одного из журналов сбоев HockeyApp:

Thread 0 Crashed:
0   libsystem_kernel.dylib         0x3167132c __pthread_kill + 8
1   libsystem_c.dylib              0x33d6729f abort + 94
2   ImageIO                        0x346c38bf png_error + 114
3   ImageIO                        0x346c2fe3 png_write_end + 46
4   ImageIO                        0x346bf069 writeOnePng + 2260
5   ImageIO                        0x346be78b _CGImagePluginWritePNG + 82
6   ImageIO                        0x346be6fd CGImageDestinationFinalize + 132
7   UIKit                          0x31346e23 UIImagePNGRepresentation + 274

Мы видели только эти журналы сбоев на устройствах под управлением iOS 5.1+ и выше. Мы действительно получали сбои от iOS 6, так что эта ошибка еще не исправлена.

Я написал тестовое приложение, которое загружает более 16 000 возможных изображений, которые может отображать наше приложение, и все они могут быть загружены и сохранены на диск без проблем. Некоторые ответы на этот gist подразумевают, что эта проблема может быть вызвана поврежденными изображениями, но, видя, как я загрузил более 16 000 изображений и никогда не имел вопрос, я не думаю, что это может быть так.

Последняя гипотеза, над которой я работаю, заключается в том, что каким-то образом загружаемые данные повреждены, и поэтому создается поврежденный UIImage. Однако все попытки создать поврежденный UIImage потерпели неудачу. Apple, похоже, создала надежный конструктор для UIImage, так что все, что я передаю, в котором недопустимо, приводит к тому, что nil возвращается из конструктора.

Кто-нибудь еще испытал что-то подобное из UIImagePNGRпредставления?

Ответ 1

Пробовали ли вы тестирование в разных условиях сети? 3G или ребро вместо Wi-Fi? Попробуйте использовать Network Link Conditioner, чтобы имитировать эти условия медленных и потерянных сетей.

Ответ 2

Вы делаете ЛЮБЫЕ вызовы UIKit из вторичных потоков? Я видел сбои, когда графические вызовы UIKit на вторичных потоках работают, но главный поток в какой-то момент падает. Существует несколько методов UIKit, которые можно использовать для вторичных потоков, но не так много.

Ответ 3

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

В моем случае фактический эффект пользователя от ошибки заключался в том, что изображение будет только частично рендерить; остальная часть изображения просто выглядит серым и поврежденным. Я храню и читаю с диска с использованием Core Data (но Core Data был потрясающе не моей проблемой).

МОЙ ФИКС:

Ранее я использовал этот метод удобства:

UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

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

NSData *resultData = [NSData dataWithContentsOfFile:imagePath];
UIImage *image = [UIImage imageWithData:resultData];

.. и он ПОСМОТРЕТЬ, чтобы решить мою проблему!

МОЯ ТЕОРИЯ

Я предполагаю, что imageWithContentsOfFile: по какой-то причине хуже справляется с некоторыми неатомическими условиями кромки по отношению к чистым базовым вызовам NSData, и по какой-то причине позволяет "читать" до того, как завершится предыдущая запись.

Надеюсь, это поможет! Удачи.

Ответ 4

Если вызов UIImagePNGRepresentation находится внутри цикла, я увидел исправление в другом SO-потоке, которое предлагает добавить sleep(1.0); после сохранения.

Ответ 5

У нас была эта проблема в приложении, работающем в масштабе. Это происходило более 1000 раз в день. Используя возможности ведения журнала в Crashlytics, мы смогли точно определить, какие изображения вызывают крах.

Появилось около 25 изображений, вызывающих крушение. Мы поняли, что каждое из этих изображений было экспортировано из Photoshop, тогда как большинство наших изображений было экспортировано из Illustrator. Изображения, сделанные в любой другой программе, которую мы пробовали, и мы никогда не могли определить, что с ними было "неправильно". Но мы реэкспортировали изображения из Illustrator, и наша частота этого сбоя снизилась до нуля.

Я понимаю, что это не дает первопричины, но подумал, что это может быть полезно для кого-то другого, испытывающего эту проблему.