png_error внутри UIImagePNGRepresentation только на iOS 5.1+

Мы наблюдаем странный сбой, когда UIImagePNGRepresentation() иногда вызывает вызовы 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 возможных изображений, которые может отображать наше приложение, и все они могут быть загружены и сохранены на диск без проблем. Некоторые ответы на этот суть подразумевают, что эта проблема может быть вызвана поврежденными изображениями, но, учитывая, что я скачал более 16 000 изображений, и у меня никогда не было проблем, я не думаю, что это может быть так.

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

Кто-нибудь еще сталкивался с чем-то подобным от UIImagePNGRepresentation?


person Senior    schedule 12.09.2012    source источник
comment
Вы знаете, на каком устройстве происходит этот сбой? Только iPhone, iPod touch или iPad?   -  person runmad    schedule 12.09.2012
comment
Мы видим это на всех устройствах, но в первую очередь на iPhone4,1, iPhone3,1 и iPhone2,1... но я думаю, что это только из-за нашей пользовательской базы. Я не нормализован по зарегистрированным устройствам.   -  person Senior    schedule 12.09.2012
comment
Может быть, это ошибка нехватки памяти? Если вы прочитаете все PNG в память, malloc() в конечном итоге вернет 0...   -  person    schedule 17.09.2012
comment
Хорошая идея — я только что создал приложение с утечкой, чтобы проверить это, но оно просто убило приложение -9.   -  person Senior    schedule 17.09.2012
comment
Вы нашли решение этому? Я получаю похожую ошибку, но она немного отличается: 3 ImageIO 0x320857c4 _cg_png_error + 84   -  person leftspin    schedule 11.02.2013
comment
Прошу прощения, но нет. В итоге мы переключились на другую библиотеку кэширования изображений, которая решила проблему. Вероятно, это была проблема с получением представления png в другом потоке.   -  person Senior    schedule 11.02.2013


Ответы (5)


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

person brynbodayle    schedule 17.09.2012
comment
Я не понимаю, какое отношение создание PNG имеет к условиям сети... UIImagePNGRepresentation вызывается только после завершения загрузки изображения. - person Senior; 17.09.2012
comment
Да, но вы можете загрузить поврежденный или частичный образ. - person brynbodayle; 17.09.2012
comment
В своем исходном посте я упомянул, что мы создали поврежденные образы и протестировали их, но безрезультатно. Спасибо за предложение. - person Senior; 17.09.2012

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

person EricS    schedule 20.09.2012
comment
К сожалению, pkill находится в потоке 0. Мы выполняем вызов UIImagePNGRepresentation в основном потоке, что забавно, потому что я собирался переместить его, чтобы он не блокировался, но я думаю, это может усугубить ситуацию? - person Senior; 20.09.2012

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

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

МОЕ ИСПРАВЛЕНИЕ:

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

UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

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

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

..и это КАЖЕТСЯ решило мою проблему!

МОЯ ТЕОРИЯ

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

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

person toblerpwn    schedule 25.12.2012
comment
Я думаю, что это может быть другой проблемой, чем то, что мы испытываем здесь. Проблема заключается не в сериализации NSData в UIImage, а в том, что когда UIImage сериализуется в NSData, поток, в котором это происходит, получает сигнал уничтожения, и поскольку это происходит в потоке пользовательского интерфейса (что само по себе уже является проблемой), приложение умирает. . - person Reid Main; 02.01.2013

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

person Or Arbel    schedule 27.05.2013
comment
К сожалению, это находится в кеше веб-изображений и потенциально может вызываться сотни раз в секунду. - person Senior; 31.05.2013

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

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

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

person tracy    schedule 18.11.2013